home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 October: Mac OS SDK / Dev.CD Oct 00 SDK1.toast / Development Kits / Mac OS / Apple Remote Access API / Documentation / ARA API / ARA API
Encoding:
Text File  |  1994-09-15  |  136.5 KB  |  443 lines  |  [ONLN/HLX2]

  1. ®
  2. Apple Remote Access
  3. Application Programming Interface (API)
  4. External Reference Specifications
  5. Note: The Apple Remote Access API provides an application programming interface to the Remote Access Manager.  It supports calls to load and unload the Remote Access Manager (RAM), create and terminate connections, retrieve the current RAM status, and to determine if a specified network address is local or remote.  Optionally, the Apple Remote Access API can display a user interface showing the process of a connection.  The parameters for the connect call can be a connection document, created with the Remote Access application. The parameters of the connection, however, may not be specified out right when connecting to ARA 2.0.  These specifications also include how to tell if Apple Remote Access is installed, and how to deal with the serial port when Apple Remote Access is in answer mode.
  6. Although every attempt has been made to verify the accuracy of the information presented, this document may contain errors and is subject to change.  ARA 2.0 features are not guaranteed.
  7. Gestalts
  8. When fully installed, Remote Access defines several new gestalt selectors.  Below are the new defines and explanation of their use.
  9. To see if serial port arbitration is installed, call _Gestalt using these defines.
  10. #define gestaltArbitorAttr                'arb '
  11. #define gestaltSerialArbitrationExists        0
  12. For example:
  13. OSErr io;
  14. // check to see if serial port arbitrating is installed…
  15. long attribs;
  16. io = Gestalt(gestaltArbitorAttr, &attribs);
  17. if ( ((io == noErr) && (attribs & (1 << gestaltSerialArbitrationExists))) )
  18.    {
  19.    // have serial port arbitration
  20.    }
  21. else
  22.    {
  23.    // no serial port arbitration
  24.    }
  25. More information on serial port arbitration is discussed in a section below.
  26. To see if Remote Access Connection Interface is available use these defines:
  27. #define gestaltRemoteAccessAttr            'strm'
  28. #define gestaltRemoteAccessExists            0
  29. To check if Remote Access support is available in the Alias Manager use these defines:
  30. #define gestaltAliasMgrAttr             'alis'    // as defined in GestaltEqu.h
  31. #define gestaltAliasMgrSupportsRemoteAppletalk    1
  32. To use ARA 2.0 features, call _Gestalt using these defines.
  33. #define gestaltRemoteAccessCallOnly            1    // checks for ARA client
  34. #define gestaltRemoteAccessMPServer            2    // checks for ARA multi-port server
  35. #define gestaltRemoteAccessVers2            3    // checks for ARA 2.0 features
  36. Serial Port Arbitration
  37. When installed Remote Access provides serial port arbitration throught the Serial Port Arbitrator tool.   All serial drivers registered with the Communications Resource Manager are arbitrated by the Serial Port Arbitrator.   
  38. To check to see if the Serial Port Arbitrator is installed, check the gestaltSerialArbitrationExists flag of the gestaltArbitorAttr Gestalt selector  (see “Gestalts” section for these defines and an example of this call).
  39. If serial port arbitration is present, call OpenDriver when you want to use a serial port.  If the driver requested is not open, OpenDriver will return a result of noErr and the reference number of the driver.  If the driver requested is open (in use), OpenDriver will return the error portInUse.  When you are finished using the driver, call CloseDriver.  OpenDriver and CloseDriver calls should always be balanced,  although the Serial Port Arbitrator will protect against multiple open/close calls. 
  40. If serial port arbitration is not present, do not use OpenDriver to determine if the driver is open.  It will return you a result of noErr and the reference number, allowing you access to a driver that another application is using.   To determine if the serial driver requested is open by another application, you must walk the DCE (Device Control Entry) unit table (see Device Driver chapter of Inside Macintosh vol II).
  41. It is important to use the new method if serial port arbitration is available.  Remote Access, when set up for answering calls, is passively using a particular serial driver.  If you use the new method, the Serial Port Arbitrator will give up the passive claim and allow your OpenDriver call to return noErr.  Later, when you call CloseDriver, Remote Access will again passively claim the port and setup the modem for answering. 
  42. Below is a code example in C illustrating how to use serial port drivers under the new and old methods:
  43. #include <GestaltEqu.h>
  44. #include <SysEqu.h>
  45. #include <Devices.h>
  46. #include <stdio.h>
  47. #define gestaltArbitorAttr             'arb '
  48. #define gestaltSerialArbitrationExists    0
  49. #define dRAMBased                    0x0040
  50. #define dOpened                    0x0020
  51. Boolean SerialArbitrationExists(void)
  52. {
  53.     long    response;
  54.     OSErr    err;
  55.     
  56.     err = Gestalt(gestaltArbitorAttr, &response);
  57.     if (err)
  58.         return false;
  59.     return ((response >> gestaltSerialArbitrationExists) & 1);
  60. }
  61. Boolean DriverIsOpen(StringPtr driverName)
  62. {
  63.     Boolean canOpen = false;
  64.     Boolean match = false;
  65.     short    index = 0;
  66.     short    count;
  67.     DCtlHandle    dceHandle;
  68.     StringPtr    namePtr;
  69.     DCtlHandle    *theUnitTable;
  70.     
  71.     // this is the low memory global containing the number of entries 
  72.     // in the Unit Table
  73.     count = *(short *)UnitNtryCnt;
  74.     
  75.     theUnitTable = *(DCtlHandle **)UTableBase;
  76.     
  77.     while ( !match && (index < count)) {
  78.         // get handle to a device control entry
  79.         dceHandle = theUnitTable[index];
  80.         
  81.         if (dceHandle) {
  82.             if (!( (**dceHandle).dCtlFlags & dRAMBased) )
  83.                 // RAM based drivers have a handle to their driver
  84.                 namePtr = (StringPtr)(**dceHandle).dCtlDriver+18;
  85.             else
  86.                 // ROM based drivers have a pointer to their driver
  87.                 namePtr = (StringPtr) (*(DCtlPtr)dceHandle).dCtlDriver+18;
  88.             // not case sensitive, diacritical marks count
  89.             if (RelString(driverName, namePtr, false, true) == 0) {
  90.                 match = true;
  91.                 canOpen = ((**dceHandle).dCtlFlags & dOpened) ? true : false;
  92.             }
  93.         }
  94.         index++;
  95.     }
  96.     return canOpen;
  97. }
  98. Boolean CRMInstalled(void)
  99. {
  100.     long    response;
  101.     OSErr    err;
  102.     
  103.     err = Gestalt(gestaltCRMAttr, &response);
  104.     if (err)
  105.         return false;
  106.     return ((response >> gestaltCRMPresent) & 1);
  107. }
  108. Str255    gDriverNames[] = {"\p.NoDrvr", 
  109.                           "\p.AOut", 
  110.                           "\p.BIn", 
  111.                           "\p.BOut",
  112.                           "\p.AppleCD",
  113.                           "\p.MPP",
  114.                           "\p.ASYC00",
  115.                           "\p.AIn"
  116.                          };
  117. #define TEST_CALL
  118. main()
  119. {
  120.     OSErr    err = noErr;
  121.     short    i;
  122.     short    numDrivers;
  123.     
  124.     printf("Test of serial port stuff\n");
  125.     if (CRMInstalled())
  126.         printf("Communication Resource Manager is installed.\n");
  127.     if (SerialArbitrationExists())
  128.         printf("Serial Arbitration exists\n");
  129.         
  130. #ifdef TEST_CALL
  131.     numDrivers = sizeof(gDriverNames) / sizeof(Str255);
  132.     for (i = 0; i < numDrivers; i++)
  133.         printf("DriverIsOpen(%#s)\treturned %s\n", 
  134.                 gDriverNames[i], DriverIsOpen(gDriverNames[i])?"True ":"False");
  135. #endif
  136. #ifdef TEST_OPEN
  137.     short    refNum;
  138.     if (!DriverIsOpen("\p.AIn"))
  139.         err = OpenDriver("\p.AIn", &refNum);
  140.     if (err)
  141.         printf("OpenDriver returned %d\n", err);
  142.     err = CloseDriver(refNum);
  143.     if (err)
  144.         printf("CloseDriver returned %d\n", err);
  145. #endif
  146. }
  147. Apple Remote Access API
  148. Common Parameters
  149. The TRemoteAccessParamBlock is a union of  all of the available Apple Remote Access API commands.  The TRemoteAccessParmHeader is a struct which consists of a DControlParamHeader followed by a DExtendedParam which is followed by a DRemoteAccessParmHeader.  The extendedCode  is used to specify the Apple Remote Access API  command wanted.  The resultStrPtr field returns a Pascal string to indicate what error occurred.  If you are not interested in the string, set this field to nil.  If you do pass a pointer however, it must point to a buffer of at least 256 bytes in length.  If the result of the call happens to be noErr, then the length byte of the string will be zero.   Since this version of Remote Access only deals with the user port, the parameter portGlobalsPtr should always be set to zero.  The csCode field should normally set to RAM_EXTENDED_CALL and the extendedType is set to REMOTEACCESSNAME.  These constants are defined in RemoteAccessInterface.h.
  150. #define DControlParamHeader \
  151.     QElem    *qLink;    // next queue entry \
  152.     short    qType;        // queue type \
  153.     short    ioTrap;    // routine trap \
  154.     Ptr    ioCmdAddr;    // routine address \
  155.     ProcPtr    ioCompletion;    // completion routine \
  156.     OSErr    ioResult;    // result code \
  157.     long    userData;    // for use by the user \
  158.     short    unused;    // unused field \
  159.     short    ioRefNum;    // driver reference number \
  160.     short    csCode;    // normally set to RAM_EXTENDED_CALL
  161.                         // for Apple Remote Access API  calls
  162. #define DExtendedParam \
  163.     DControlParamHeader \
  164.     Ptr    hReserved1; \
  165.     Ptr    hReserved2; \
  166.     Ptr    resultStrPtr; \    // set to zero if result string is unwanted
  167.     Ptr    extendedType;        // pointer to identifier string, normally set to                         // REMOTEACCESSNAME for Apple Remote Access API  calls
  168. #define DRemoteAccessParmHeader \
  169.     DExtendedParam \
  170.     short    extendedCode;        // for use by extended call proc \
  171.     Ptr    portGlobalsPtr;    // pointer to globals for this port (0=userport) \
  172. struct TRemoteAccessParmHeader
  173. {
  174.     DRemoteAccessParmHeader
  175. };
  176. typedef struct TRemoteAccessParmHeader TRemoteAccessParmHeader;
  177. union TRemoteAccessParamBlock
  178. {
  179.     TRemoteAccessParmHeader    HDR;        // header pb
  180.     TRemoteAccessParmHeader    LOAD;        // load pb
  181.     TRemoteAccessParmHeader    UNLOAD;    // unload pb
  182.     TRemoteAccessConnectParam    CONNECT;    // connect pb
  183.     TRemoteAccessDisconnectParam     DISCONNECT;    // disconnect pb
  184.     TRemoteAccessStatusParam    STATUS;    // get current status
  185.     TRemoteAccessIsRemoteParms    ISREMOTE;    // check network address location
  186.     TRemoteAccessPasswordMunger    MUNGEPW;    // run password through munger
  187.     TRemoteAccessGetCodeHooks    CODEHOOKS;    // get internal code hooks
  188.     /* 2.0 and above only… */
  189.     T976SetOnlineNotify    ONLINE_NOTIFY    // used to toggle the state
  190.                     // of notification
  191.     unsigned char        filler[256];        // set the minimum size of this                                 // parameter block
  192. };
  193. typedef union TRemoteAccessParamBlock TRemoteAccessParamBlock;
  194. typedef TRemoteAccessParamBlock *TPRemoteAccessParamBlock;
  195. Load
  196. The load command is used to ensure that the Remote Access Manager is loaded into memory and must be used before making a Connect call .  It uses the standard TRemoteAccessParmBlock as the parameter block.  The example code below shows how it works.  To use the MungePW command, it is not necessary to use the load command first.
  197. #include “RemoteAccessInterface.h”
  198. void LoadRemoteAccess()
  199. {
  200.     TRemoteAccessParamBlock loadPB;
  201.     
  202.     loadPB.LOAD.csCode = RAM_EXTENDED_CALL;    // extended call
  203.     loadPB.LOAD.resultStrPtr = nil;    // result string
  204.     loadPB.LOAD.extendedType = REMOTEACCESSNAME;    // to remote access
  205.     loadPB.LOAD.extendedCode = CmdRemoteAccess_Load;    // try to load
  206.     PBRemoteAccess(&loadPB, false);    // issue sync call
  207.     if (loadPB.LOAD.ioResult)
  208.         ShowError(loadPB.LOAD.ioResult);
  209. }
  210. Unload
  211. The unload command is used to release the Remote Access Manager and free its memory.   It uses the standard TRemoteAccessParmBlock as the parameter block and can be issued immediately after making a Connect call.  This allows the Remote Access Manager to be unloaded as soon as an active connection is terminated with a disconnect, if no other clients have loaded Remote Access.  Below is an example unload call.
  212. #include “RemoteAccessInterface.h”
  213. void UnloadRemoteAccess()
  214. {
  215.     TRemoteAccessParmBlock unloadPB;
  216.     
  217.     // unload the code (will not actually go away till this connection is done)
  218.     unloadPB.UNLOAD.csCode = RAM_EXTENDED_CALL;    // extended call
  219.     unloadPB.UNLOAD.resultStrPtr = nil;    // result string
  220.     unloadPB.UNLOAD.extendedType = REMOTEACCESSNAME;    // to remote access
  221.     unloadPB.UNLOAD.extendedCode = CmdRemoteAccess_Unload;    // try to unload
  222.     PBRemoteAccess(&unloadPB, false);    // issue sync call
  223.     if (unloadPB.UNLOAD.ioResult)
  224.         ShowError(unloadPB.UNLOAD.ioResult);
  225. }
  226. Connect
  227. This call is used to initiate an outgoing connection.  When you are connected in this mode you will still retain access to your current network.  Network numbers are re-mapped in a limited way in order to solve problems of network number conflicts between the two machines being directly connected, thus ensuring they will always be accessible to each other.  Unfortunately, it is not possible to solve all of the other possible conflicts due to the limited number of network numbers available.  In order to provide a method of ensuring access to all networks on the destination network a guaranteed access method is available.  When connected in this mode, you will lose access to all services beyond those on the same single network number that the calling machine belongs to.  In order to notify clients of the AppleTalk stack that a network will no longer be reachable we have created a new AppleTalk Transition Queue event.  (See Network Transition Events later in this document.)  When connecting the client passes in a TRAConnectInfoTemplate, or the FSSpec of a document which contains the connect parameters.  The connect parameter block contains the optionFlags field which specifies the connect options.  The flags are shown below:
  228. // connect option flags
  229. #define kNSCanInteract    0x00000001    // User interaction (password prompt) is OK
  230. #define kNSShowStatus    0x00000002    // show the status of the connect or disconnect call
  231. #define kNSConnectDocument    0x00000004    // connect using the specified document using FSSpec
  232. #define kNSPassWordSet    0x00000010    // use the specified password field when connecting                                 // by document
  233. // 2.0 and above…
  234. #define kNS2SavvyFlags    0x40000000    // Set to use the next 2 flags below for only ARA                         // 2.0 aware applications.
  235. #define kNSAR2Connection    0x00000020    // connecting to a 2.0 server. 
  236. #define kNSNotifyWhileConnected 0x00000040    // display cute notification icon while connected.
  237. The kNSCanInteract flag allows interaction with the user to get the password if necessary or prompt the user to change their password if the server requires it.  The kNSShowStatus flag enables the connection status display.  The display is modal dialog which updates with new messages as the connection progresses.  When the kNSConnectDocument flag is set, the Apple Remote Access API  will use the specified ARA 2.0 document for the connect parameters (i.e. user name, password) of the TRAConnectInfoTemplate.  The document is specified by the FSSpec record which contains vRefNum (volume reference number), parID (directory ID), and name (pointer to Pascal style string containing the document name).  No other parameters need to be supplied.  The kNSPassWordSet flag overrides the saved password when connecting by document or by PB and forces Apple Remote Access API  to use the passWord field in cleartext.  If the kNSPassWordSet flag is clear and the passwordSaved flag is set, then the client must supply a munged password.  The kNS2SavvyFlags is set if using ARA 2.0 features.  The kNSAR2Connection flag indicates the connection is to a 2.0 server.  If this bit is not set, it is assumed that it is a 1.0 connection.  The kNSNotifyWhileConnected flag will display a notification icon on the Apple Menu while the user is connected.
  238. In this release, the client may not connect by parameter block (PB). Use the kNSConnectDocument flag to connect with a specified ARA 2.0 document. The fields in the connectInfo record are discussed below.  They are filled by the specified ARA 2.0 document.  Within this record is a version which is used by the connect template (currently set to 1).  The ltType parameter specifies the type of the link tool that will be used in this connection. The ARA 2.0 connect document specifies the length and points to the address used in connecting by setting up  addressInfoLength and addressInfoPtr.  The ltSpecificTemplatePtr is expected to point to the template of the link tool specific parms.  An example of link tool specific parms might be items such as the serial port reference (.AIn, .AOut) that is used in the Modem Link Tool.  A userName is passed in that indicates the name of the user logging in.   A passWord is specified if the user is not logging in as a guest.  If the user wants to be a guest, the guestLogin flag is set.   The connectReminderTimer is used if the caller wants to be reminded that a connection is in progress.  This field is set to the number of seconds between reminders, and can be set to zero if no reminders are wanted.  If a connectReminderTimer is set you must set the connectOKWaitTimer that indicates how long the reminder dialog will wait for OK to be hit before disconnecting.
  239. struct TRAConnectInfoTemplate
  240. {
  241.     unsigned long version;    // version of this format
  242.     unsigned long ltType;    // Link Tool type
  243.     long addressInfoLength;    // length of the address information
  244.     Ptr addressInfoPtr;    // pointer to connect address info
  245.     long ltSpecificTemplateLength;     // length of the ltspecific information
  246.     Ptr ltSpecificTemplatePtr;    // pointer to link tool specific params
  247.     unsigned char passWord[PASSWORDBUFSIZE];    // user password
  248.     unsigned char userName[USERNAMESIZE];    // user name    
  249.     unsigned long connectReminderTimer;    // value for connection reminder in seconds
  250.     unsigned long connectOKWaitTimer;    // how long to wait for OK on reminder timer
  251.     Boolean guestLogin;    // try to log in as a guest    
  252.     Boolean passwordSaved;    // set if password is saved    
  253.     Boolean guaranteedAccess;    // flag to guarantee access to servers internet
  254. };
  255. typedef struct TRAConnectInfoTemplate TRAConnectInfoTemplate;
  256. typedef TRAConnectInfoTemplate *TPRAConnectInfoTemplate;
  257. struct TRemoteAccessConnectBlock
  258. {
  259.     DRemoteAccessParmHeader
  260.     TRAConnectInfoTemplate connectInfo;    // The connection information template
  261.     unsigned long optionFlags;    // bit mapped connect option flags 
  262.     FSSpec fileInfo;    // file info for connect document
  263. };
  264. typedef struct TRemoteAccessConnectBlock TRemoteAccessConnectBlock;
  265. The following is an example connection procedure:
  266. #include “RemoteAccessInterface.h”
  267. void DoConnect()
  268. {
  269.     TRemoteAccessParamBlock connectPB;
  270.     Str255 PathName = “MyHardDisk:Remote Access:Connect Document”;
  271.     LoadRemoteAccess();    // Get the Remote Access Manager
  272.         // loaded
  273.     connectPB.CONNECT.csCode = RAM_EXTENDED_CALL;    // extended call
  274.     connectPB.CONNECT.resultStrPtr = nil;    // don’t want result strings
  275.     connectPB.CONNECT.extendedType = REMOTEACCESSNAME;      // to Remote Access
  276.     connectPB.CONNECT.extendedCode = CmdRemoteAccess_DoConnect;     // connect command
  277.     connectPB.CONNECT.portGlobalsPtr = nil;    // use the user port
  278.     connectPB.CONNECT.fileInfo.vRefNum = 0;    // Use the full pathname
  279.     connectPB.CONNECT.fileInfo.parID = 0;
  280.     strcpy(&PathName,&connectPB.CONNECT.fileInfo.name);    // copy the string to fileInfo.name
  281.     // Ask for password if needed, use connection document, & show connection status
  282.     connectPB.CONNECT.optionFlags = kNSCanInteract | kNSConnectDocument | kNSShowStatus
  283.                              | kNS2SavvyFlags    // Use the 2.0 flags below
  284.                              | kNSAR2Connection     // connection to a 2.0 server
  285.                            | kNSNotifyWhileConnected;    // displaying notification icon
  286.     PBRemoteAccess(&connectPB, false);      // issue sync call
  287.     if (connectPB.CONNECT.ioResult)
  288.       ShowError(connectPB.CONNECT.ioResult);     // Do Error reporting and recovery
  289.     UnloadRemoteAccess();    // Unload when disconnected.
  290. } // DoConnect
  291. Disconnect
  292. The disconnect command is used to terminate an existing session or cancel one that is being created.  If you only want to disconnect a session that was connected with a specific parameter block you can do so by setting a pointer to the parameter block used to issue the connect in abortOnlyThisPB.  If you want to disconnect a connection created by anyone, you set the abortOnlyThisPB field to zero.  If you are disconnecting an outgoing call, you pass zero in portGlobalsPtr.  Disconnecting ports other than the userport, is not supported in this version.  You should always set disconnectin to zero.  The option kNSShowStatus will cause the Apple Remote Access API  to display the status dialog during the disconnect.
  293. #define kNumWarnEntriesMax  5    // number of entries in warn array
  294. struct TRemoteAccessDisconnectParam
  295. {
  296.     DRemoteAccessParmHeader
  297.     unsigned long disconnectin;    // Note: Set this parameter to 0
  298.     TPRemoteAccessParamBlock abortOnlyThisPB;    // only abort a connection opened by this pb
  299.     unsigned long warnArr[kNumWarnEntriesMax];     // set warn times here in seconds (zero all if
  300.         // no warnings)                
  301.     unsigned long optionFlags;    // bit mapped connect option flags
  302. };
  303. typedef struct TRemoteAccessDisconnectParam TRemoteAccessDisconnectParam;
  304. The following is an example of  a simple disconnect procedure.  It will disconnect any existing active connection.
  305. #include “RemoteAccessInterface.h”
  306. void DoDisconnect()
  307. {
  308.     TRemoteAccessParamBlock disconnectPB;
  309.     // set up the Remote Access PB
  310.     disconnectPB.DISCONNECT.csCode = RAM_EXTENDED_CALL;        // extended call
  311.     disconnectPB.DISCONNECT.resultStrPtr = nil;        // don’t want result strings
  312.     disconnectPB.DISCONNECT.extendedType = REMOTEACCESSNAME;         // to Remote Access
  313.     disconnectPB.DISCONNECT.extendedCode = CmdRemoteAccess_Disconnect;  // disconnect command
  314.     disconnectPB.DISCONNECT.portGlobalsPtr = nil;        // user port
  315.     disconnectPB.DISCONNECT.abortOnlyThisPB = nil;        // don't get tied to any specific pb
  316.     disconnectPB.DISCONNECT.optionFlags = 0| kNSShowStatus;    // show status while disconnecting
  317.     PBRemoteAccess(&disconnectPB, false);        // issue sync call
  318.     if (disconnectPB.DISCONNECT.ioResult)
  319.       ShowError(disconnectPB.DISCONNECT.ioResult);         // Do Error reporting and recovery
  320. }
  321. IsRemote
  322. The "IsRemote" command is used to determine if a network address is remote or local.  If the network is remote, the call will optionally return the information necessary to make the connection to the remote network. The parameter theAddress contains the network address to be checked.   The format of theAddress is the same as for the struct AddrBlock as defined in AppleTalk.h:
  323.     Bytes 3 & 2 (High Word): Network Number
  324.     Byte 1: Node Number
  325.     Byte 0 (Low Byte): Socket Number
  326. The optionFlags parameter is used for getting, or disposing, connection information.  The following flags are defined:  
  327. #define ctlir_getConnectInfo    0x01    // will get connect info if address remote
  328. #define ctlir_disposeConnectInfo     0x02    // will dispose info in connectInfoPtr properly
  329. If the ctlir_getConnectInfo flag is set, and the network address is remote, the information necessary to create the remote connection is returned.  If the ctlir_disposeConnectInfo flag is set, the connect information structure pointed to by connectInfoPtr, is disposed of properly.
  330. The locationIsRemoteFlag parameter is a flag that is returned true if the network address is remote.  The connectInfoLength parameter indicates the length of the connect information.  The connectInfoPtr is a pointer to the connection information for connecting with the remote address.  These values are returned when the network address is remote, and the ctlir_getConnectInfo flag is set.  
  331. struct TRemoteAccessIsRemoteParms
  332. {
  333.     DRemoteAccessParmHeader
  334.     long theAddress;             // address that is to be checked
  335.     unsigned long optionFlags;    // Set to ctlir_getConnectInfo or
  336.         // ctlir_disposeConnectInfo, if zero only checks
  337.         // theAddress
  338.     Boolean locationIsRemoteFlag;    // returns true if address is remote
  339.     long connectInfoLength;        // length of the following data    
  340.     TPRAConnectInfoTemplate connectInfoPtr;    // The connection information template pointer    
  341. };
  342. typedef struct TRemoteAccessIsRemoteParms TRemoteAccessIsRemoteParms;
  343. Status
  344. The status command is used to obtain information about Remote Access.  The information you can obtain is how long a connection has been active, how much time remains in the connection, the name of the user that made an answering connection, the name of the computer you are connected to on a calling connection, and the last message that was posted.  The statusBits parameter is used to determine if a connection is active, starting up, in the process of tearing down, if the connection is an answering or calling connection, if the computer is enabled to receive answer calls or if a disconnect is in progress. The following flags are defined: 
  345. // bits passed back in statusBits
  346. #define CctlConnected           0x00000001    // set when connected
  347. #define CctlAnswerEnable        0x00000004    // set when we are set to answer calls
  348. #define CctlServerMode          0x00000008    // set for answer mode, clear for call mode
  349. #define CctlConnectionAborting  0x00000010    // connection is being torn down
  350. #define CctlConnectInProg       0x00000020    // set when connection in progress or fully
  351.                                 // connected
  352. #define CctlDisconnectInStarted 0x00008000    // somebody has started a disconnectIn
  353. #define ctlAR2Connection        0x02000000    // set when this connection is to a 2.0 server
  354. #define ctlNotifyWhileConnected 0x04000000    // set when the user wants to be reminded while             // connected.
  355. #define ctlConnectedToMPS       0x08000000    // set when client is connected to a multi-port             // server
  356. #define CctlMultiNodeReady      0x80000000    // shows if we currently have a multinode                     // address to enable answer mode.
  357. The following struct is used when making a status call:
  358. struct TRemoteAccessStatusParam
  359. {
  360.     DRemoteAccessParmHeader
  361.     unsigned long statusBits;    // bits for current status
  362.     unsigned long timeConnected;    // number of seconds we have been connected
  363.     unsigned long  timeLeft;    // number of seconds remaining in connection
  364.         // (0xffffffff infinite)
  365.     unsigned char *userNamePtr;    // returns user name, expects pointer to buffer                 // of USERNAMESIZE if non nil
  366.     unsigned char  *connectedToNamePtr;    // returns name of where we connected to,                     // expects pointer to buffer of USERNAMESIZE if                 // non nil
  367.     TPRemoteAccessParamBlock connectedByParamPtr; // a pointer to the parameter block
  368.         // "initiating" the connection if we are                     // connected
  369.     TPRemoteAccessParamBlock statusConnectedByParamPtr; // a pointer to the parameter block
  370.         // "initiating" the connection when status was
  371.         // posted
  372.     unsigned char  *theLastStatusMsgPtr;    // expects pointer to buffer of size                     // MAXSTATUSMSGSIZE
  373.     unsigned char  *statusUserNamePtr;    // pointer to buffer of size USERNAMESIZE
  374.     long  statuslttype;    // link tool type
  375.     long  statusmsgOptionFlags;    // classification of message type
  376.     long  statusMsgNum;    // specific message number
  377.     long  statusMsgSeqNum;    // pass in zero if always want status, otherwise                 // use last value, if status is new, new number
  378.         // is returned
  379.     unsigned long  userSignature;    // signature of port creator
  380.     unsigned long  userRefCon;    // refcon of port creator
  381. };
  382. typedef struct TRemoteAccessStatusParam TRemoteAccessStatusParam;
  383. An example status call that determines the state Remote Access is in.
  384. #include “RemoteAccessInterface.h”
  385. void GetStatus()
  386. {
  387.     TRemoteAccessParamBlock statusPB;
  388.     Str255 UserName,connectedTo,lastMessage;
  389.     long statusBits;
  390.     statusPB.STATUS.csCode = RAM_EXTENDED_CALL;    // extended call
  391.     statusPB.STATUS.resultStrPtr = nil;    // put results here
  392.     statusPB.STATUS.portGlobalsPtr = nil;    // do UserPort
  393.     statusPB.STATUS.extendedType = REMOTEACCESSNAME;    // to Netshare
  394.     statusPB.STATUS.extendedCode = CmdRemoteAccess_Status;      // status command
  395.     statusPB.STATUS.userNamePtr = &UserName;
  396.     statusPB.STATUS.connectedToNamePtr = &connectedTo;
  397.     statusPB.STATUS.theLastStatusMsgPtr = &lastMessage;
  398.     statusPB.STATUS.statusUserNamePtr = nil;
  399.     statusPB.STATUS.statusMsgSeqNum = 0;    
  400.     PBRemoteAccess(&statusPB, false);
  401.     if (statusPB.STATUS.ioResult)
  402.           ShowError(statusPB.STATUS.ioResult);     // Do Error reporting and recovery
  403.     else
  404.     {
  405.             // now decode the flag bits into words
  406.             statusBits = statusPB.STATUS.statusBits;
  407.             if (statusBits & CctlServerMode)
  408.                 printf("Answer connection\n");
  409.             if (statusBits & CctlConnected)
  410.                 printf("Calling connection\n");
  411.             if (statusBits & CctlConnectionAborting)
  412.                 printf("Cancel in progress\n");
  413.             if (statusBits & CctlAnswerEnable)
  414.                 printf("Waiting for incoming call\n");
  415.             if (statusBits & CctlConnectInProg)
  416.                 printf("Connection in progress\n");
  417.     }
  418. } // GetStatus
  419. GetUserPortGlobalsPtr
  420. In order to make the RAM Status call on a machine that is setup to answer calls, you must first make the GetUserPortGlobalsPtr call to retrieve a pointer to the globals for the user port.
  421. The Apple Remote Access (ARA)  Personal software supports dial-out and answering capabilities through a single port called the “user” port (the modem or printer port on your Mac). This means that when you setup your machine to answer calls, you can answer only one call at a time on the user port. However, the underlying ARA architecture was designed so that multiple ports may be supported (in a dial-in server for example).
  422. When you dial-out on your Mac and establish an ARA connection, ARA internally allocates the data structures for the user port - but not until a connection is actually made. This is why, for example, the Status call will return the -5833 ERR_PORTDOESNOTEXIST error on the originating machine if there is no active connection. Once a connection has been made on a machine that is the originator of the connection, the Status call should return no error, because the data structures for the port will have been created.
  423. When you make the Status call on a machine that is setup to answer calls (the answer calls box is checked in the Remote Access Setup control panel), you will find that you always get the -5833 ERR_PORTDOESNOTEXIST error. The reason for this is that when ARA is in answer mode it needs to be able to uniquely identify each connection with a separate portGlobalsPtr, because in the future there may be support for more than one connection on a single machine. Therefore, on a machine that is setup to answer calls, you must first retrieve the portGlobalsPtr for the user port before the Status call can be made. This is accomplished with the GetUserPortGlobalsPtr call. This call makes use of the familiar TRemoteAccessParmHeader structure.  The pointer to the port globals for the user port is returned in the portGlobalsPtr field upon completion of the call. Here are the data structures used by this call:
  424. The fields in the TRemoteAccessParmHeader structure used for the GetUserPortGlobalsPtr call to the Remote Access Manager are defined as follows:
  425. ->    12    ioCompletion    long    pointer to completion routine
  426. <-    16    ioResult    word    result code
  427. ->    20    userData    long    for use by the user
  428. ->    26    ioRefNum    word    driver reference number
  429. ->    28    csCode        word    call command code
  430. ->    40    extendedType    long    pointer to identifier string
  431. ->    42    extendedCode    word    for use by extended call procedure
  432. <->    44    portGlobalsPtr long    pointer to globals for this port (0 = return user                                 port globals)
  433. Here are the detailed descriptions of the parameter block fields used by this call:
  434. ioCompletion    pointer to completion routine.
  435. ioResult    result code returned by the call.
  436. userData    user data for use by the user.
  437. ioRefNum    driver reference number.
  438. csCode    command code, normally set to RAM_EXTENDED_CALL.
  439. extendedType    should be set to REMOTEACCESSNAME.
  440. extendedCode    set to 54 to indicate the GetUserPortGlobalsPtr call.
  441. portGlobalsPtr    returns a pointer to the globals for the port. On input pass 0 to indicate                 you want the user port globals.
  442. The following result codes can be returned by the GetUserPortGlobalsPtr call:
  443. noErr        0    no error.
  444. ERR_PORTDOESNOTEXIST    -5833    port does not exist.
  445. ERR_PORTSHUTDOWN        -5832    port is shutting down.
  446. The following is an example of how you would use the GetUserPortGlobalsPtr call prior to making a Status call.
  447. #include    "RemoteAccessInterface.h"
  448. Str255    ResultStr;
  449. Str255    UserName;
  450. Str255    LastMessage;
  451. Str255    ConnectedTo;
  452. #define CmdRemoteAccess_GetUserPortGlobalsPtr 54
  453. void DoStatus()
  454. {    
  455. TRemoteAccessParamBlock    pb;
  456.     
  457.   /* Ask LTM driver for PortGlobals address */
  458.     
  459.   pb.HDR.csCode = RAM_EXTENDED_CALL;        /* extended call */
  460.   pb.HDR.extendedType = (Ptr)REMOTEACCESSNAME;    /* to Netshare */
  461.   pb.HDR.extendedCode = CmdRemoteAccess_GetUserPortGlobalsPtr; /* get user port globals */
  462.   pb.HDR.portGlobalsPtr = nil;             /* 0 = return user port globals */
  463.   PBRemoteAccess( &pb, false );
  464.   if (pb.HDR.ioResult != noErr)
  465.     HandleError(pb.HDR.ioResult);
  466.   else
  467.   {
  468.     /* Issue ARA Status Call */
  469.     
  470.     ResultStr[0] = 0;
  471.     pb.STATUS.resultStrPtr = (Ptr)ResultStr;     /* put results here */
  472.     pb.STATUS.extendedCode = CmdRemoteAccess_Status;     /* status command */
  473.     pb.STATUS.userNamePtr = UserName;
  474.     pb.STATUS.connectedToNamePtr = ConnectedTo;
  475.     pb.STATUS.theLastStatusMsgPtr = LastMessage;
  476.     pb.STATUS.statusUserNamePtr = 0;
  477.     pb.STATUS.statusMsgSeqNum = 0;
  478.     PBRemoteAccess( &pb, false );
  479.     if (pb.STATUS.ioResult != noErr)
  480.       HandleError(pb.STATUS.ioResult);
  481.   }
  482. }
  483. Thus, to make sure that the RAM Status call will work on machines that are setup to answer calls, you will need to first make the GetUserPortGlobalsPtr call so that the Remote Access Manager knows which port to return status information for.
  484. MungePW
  485. The MungePW command is used to encrypt a password to be stored in a document.  Normally, when connecting by document, it is not necessary to use this command, since the password in a document is stored in encrypted format.   It uses a struct TRemoteAccessPasswordMunger with the inputs username pointer and password pointer.  The reserved field should always be set to zero.  The munged password is return in the data buffer pointed to by passWordPtr.  It is not necessary to call the Load command before using MungePW.  The maximum username and password lengths are defined in the RemoteAccessInterface.h header file.
  486. struct TRemoteAccessPasswordMunger
  487. {
  488.     DRemoteAccessParmHeader
  489.     unsigned char *userNamePtr;    // pointer to username string
  490.     unsigned char *passWordPtr;    // user password
  491.     unsigned short reserved;        // must set to zero
  492. };
  493. typedef struct TRemoteAccessPasswordMunger TRemoteAccessPasswordMunger;
  494. Below is an example routine that calls and gets the password in *passWordPtr munged.
  495.  #include “RemoteAccessInterface.h”
  496. void MungePassword(UserName, PassWord)
  497. unsigned char *UserName, *PassWord;
  498. {
  499.     TRemoteAccessPasswordMunger mungePB;
  500.     
  501.     mungePB.MUNGEPW.csCode = RAM_EXTENDED_CALL;     // extended call
  502.     mungePB.MUNGEPW.resultStrPtr = nil;         // result string
  503.     mungePB.MUNGEPW.extendedType = REMOTEACCESSNAME; // to remote access
  504.     mungePB.MUNGEPW.extendedCode = CmdRemoteAccess_PassWordMunger;
  505.     mungePB.MUNGEPW.userNamePtr = (unsigned char *) &UserName;
  506.     mungePB.MUNGEPW.passWordPtr = (unisgned char *) &password;
  507.     PBRemoteAccess(&mungePB, false);    // issue sync call
  508.             // and encrypted the eight bytes in password
  509.     if (mungePB.MUNGEPW.ioResult)
  510.         ShowError(mungePB.MUNGEPW.ioResult);
  511.     
  512. } // MungePassword
  513. GetCodeHooks
  514. The GetCodeHooks command is used to return a pointer to the remapper procedure.  This routine can then be called to do special remappings for applications passing network addresses as part of their data.  The call can be made with the clients network number and the node number and this routine will return the remapped equivalents.
  515. struct TRemoteAccessGetCodeHooks
  516. {
  517.     DRemoteAccessParmHeader
  518.     RemmaperProcPtr remapperProc;    // quick vector to remapper code
  519. };
  520. typedef struct TRemoteAccessGetCodeHooks TRemoteAccessGetCodeHooks;
  521. The routine returned by this call is defined as follows:
  522. pascal void DoRemapper(unsigned long whereNet, unsigned long incomingFlag, unsigned long sourceSwapFlag, unsigned short *theNet, unsigned char *theNode)
  523.     
  524. whereNet-> This value has the net where this packet just came from or is going to, it is needed to determine if any remapping should even take place.
  525. incomingFlag-> Set to true if data is incoming, false if data is outgoing.
  526. sourceSwapFlag-> Set to true if a source style swap is to be used.  A source style swap means that we do remappings based on the address being a source address. If this flag is false, destination style swaps are done.
  527. theNet-> Pointer to unsigned short containing the net to be remapped.
  528. theNode-> Pointer to unsigned char containing the node to be remapped.
  529.  #include “RemoteAccessInterface.h”
  530. TestRemapper()
  531. {
  532.     TRemoteAccessParamBlock  getcodehooksPB;
  533.     unsigned short rNet;
  534.     unsigned char rNode;
  535.     ulong whereNet;
  536.   getcodehooksPB.CODEHOOKS.csCode = RAM_EXTENDED_CALL;        /* extended call */
  537.   getcodehooksPB.CODEHOOKS.portGlobalsPtr = nil;              /* do UserPort  */
  538.   getcodehooksPB.CODEHOOKS.extendedType = (Ptr)REMOTEACCESSNAME;  /* to Netshare  */
  539.   getcodehooksPB.CODEHOOKS.extendedCode = CmdRemoteAccess_GetCodeHooks; /* GetCodeHooks */                                 /*command */
  540.   PBRemoteAccess( &getcodehooksPB, false );
  541.   if (getcodehooksPB.CODEHOOKS.ioResult == noErr)
  542.   {
  543.        /* address we want remapped */
  544.        rNet = 0;
  545.        rNode = 51;
  546.        whereNet = 2200;
  547.                                                     (*getcodehooksPB.CODEHOOKS.remapperProc)(whereNet,false,true,(uPt r)&rNet,(uPtr)&rNode);
  548.   
  549.     }
  550. }
  551. Network Transition Events
  552. Network transition events are generated by Remote Access to inform interested clients that network connectivity has changed.  The type of change is indicated by the newConnectivity flag.  If this flag is true, new connectivity is being added (i.e. a connection to a new internet has taken place).  In this case, all network addresses will be returned as reachable.  If the newConnectivity flag is false, certain networks are no longer reachable.  Since Remote Access is connection based and internally functions much like a router it has knowledge of where a specific network exists.  Remote Access can take advantage of that knowledge during a disconnect to inform AppleTalk clients that a network is no longer reachable.  This information can be used by the AppleTalk client to age out connections immediately rather than waiting a potentially long period of time before discovering that the other end is no longer reachable.
  553. When Remote Access is disconnecting, it will generate a "Network Transition Event (theEvent=5)" through the AppleTalk transition queue.   A client upon receiving such a message can ask Remote Access (through a network validate hook passed to the client) if a specific network is still reachable.  If the network is still reachable, true will be returned.  A client can then continue to check other networks he is interested in until he has learned the status of each of them.  After a client is finished checking his networks he returns to Remote Access where the next AppleTalk transition queue client is called.
  554. Since the "Network Transition Event" is transitional, it is important to realize that the information that the network validate hook returns is only valid if a client has just been called as a result of a transition.  In other words, a client can only validate networks when it has been called to handle a "Network Transition Event".  It is also important to realize that the "Network Transition Event" can be called as the result of an interrupt, so a client should obey all of the normal conventions involved at being called at this time (i.e. don't ask for memory from the memory manager, etc.).
  555. The following information assumes you have already installed yourself into the AppleTalk transition queue.
  556. ATTransNetworkTransition
  557. The ATTransNetworkTransition event will be generated whenever a network transition occurs.  You will be passed the following information using C calling conventions:
  558. ClientTransitionHandler(long theEvent, Ptr aqe, TNetworkTransition *thetrans);
  559. theEvent    <---    will be set to ATTransNetworkTransition
  560. aqe        <---    points to transition task struct
  561. thetrans    <---    points to the TNetworkTransition struct
  562.  
  563. The TNetworkTransition struct passed to you is defined as:
  564. typedef pascal ulong (*NetValidProcPtr)(uPtr,AddrBlock);
  565. typedef struct TNetworkTransition
  566. {
  567.     uPtr private;    // pointer used internally by 976
  568.     NetValidProcPtr netValidProc;    // pointer to the network valid proc
  569.     Boolean newConnectivity;    // true=new connectivity, false=loss of connectivity
  570. } TNetworkTransition;
  571. To check a network number for validity the client uses the netValidProc to call Remote Access.  This call is defined as follows:
  572. long netValidProc(TNetworkTransition *thetrans, unsigned long theAddress);
  573. thetrans    --->    pass in the TNetworkTransition struct given to you when your
  574.             transition handler was called.
  575. theAddress     --->    this is the network address you want checked.  The format of theAddress is the same as for the struct AddrBlock as defined in AppleTalk.h:
  576.             Bytes 3 & 2 (High Word): Network Number
  577.             Byte 1: Node Number
  578.             Byte 0 (Low Byte): Socket Number
  579. Return codes    
  580.     TRUE    network is still reachable
  581.     FALSE    network is no longer reachable
  582. Error Codes
  583. // ------------------------------------------------------------------------------
  584. // MNP Error Codes - MNPInterface.h
  585. // ------------------------------------------------------------------------------
  586. #define MNP_ERR_BASE    -6050        // base for MNP driver errors
  587. #define ERR_MNP_NEGOTIATION_FAILURE    (MNP_ERR_BASE-1)    // Connection parameter negotiation 
  588.                                     // failure
  589. #define ERR_MNP_CONNECT_TIME_OUT    (MNP_ERR_BASE-2)    // Connect request (acceptor mode)     
  590.                                     // timed out
  591. #define ERR_MNP_NOT_CONNECTED    (MNP_ERR_BASE-3)    // Not connected
  592. #define ERR_MNP_ABORTED    (MNP_ERR_BASE-4)    // Request aborted by disconnect
  593.                                     // request
  594. #define ERR_MNP_ATTENTION_DISABLED    (MNP_ERR_BASE-5)    // Link attention service is not 
  595.                                     // enabled
  596. #define ERR_MNP_CONNECT_RETRY_LIMIT    (MNP_ERR_BASE-6)    // Connect (initiator mode) request 
  597.                                     // retry limit reached. 
  598. #define ERR_MNP_COMMAND_IN_PROGRESS    (MNP_ERR_BASE-7)    // Command already in progress.
  599. #define ERR_MNP_ALREADY_CONNECTED    (MNP_ERR_BASE-8)    // Connection already established.
  600. #define ERR_MNP_INCOMPATIBLE_PROT_LVL    (MNP_ERR_BASE-9)    // Connection failed due to
  601.                                     // incompatible protocol levels
  602. #define ERR_MNP_HANDSHAKE_FAILURE    (MNP_ERR_BASE-10)    // Connection handshake failed.
  603. // ------------------------------------------------------------------------------
  604. // Netshare Error Codes - RemoteAccessInterface.h
  605. // ------------------------------------------------------------------------------
  606. #define ERR_BASE    -5800
  607. #define ERR_NOTCONNECTED    (ERR_BASE-0)
  608. #define ERR_CONNECTIONABORTED    (ERR_BASE-1)
  609. #define ERR_ALREADYCONNECTED    (ERR_BASE-2)
  610. #define ERR_COMMANDALREADYINPROGRESS    (ERR_BASE-3)
  611. #define ERR_BADVERSION    (ERR_BASE-4)
  612. #define ERR_INSHUTDOWN    (ERR_BASE-5)
  613. #define ERR_CONNECTIONABORTING    (ERR_BASE-6)
  614. #define ERR_ALREADYENABLED    (ERR_BASE-7)
  615. #define ERR_ZONEBUFBADSIZE    (ERR_BASE-8)
  616. #define ERR_CONNECTTIMEDOUT    (ERR_BASE-9)
  617. #define ERR_CONNECTUSERTIMEDOUT    (ERR_BASE-10)
  618. #define ERR_BADPARAMETER    (ERR_BASE-11)
  619. #define ERR_NOMULTINODE    (ERR_BASE-12)
  620. #define ERR_ATALKNOTACTIVE    (ERR_BASE-13)
  621. #define ERR_NOCALLBACKSUPPORT    (ERR_BASE-14)
  622. #define ERR_NOTOPENEDBYTHISPB    (ERR_BASE-15)
  623. #define ERR_NOGLOBALS    (ERR_BASE-16)
  624. #define ERR_NOSMARTBUFFER    (ERR_BASE-17)
  625. #define ERR_BADATALKVERS    (ERR_BASE-18)
  626. #define ERR_VLD8_CONNECT    0
  627. #define ERR_VLD8_CALLBACK    (ERR_BASE-19)
  628. #define ERR_VLD8_BADVERSION    (ERR_BASE-20)
  629. #define ERR_VLD8_BADUSER    (ERR_BASE-21)
  630. #define ERR_VLD8_BADPASSWORD    (ERR_BASE-22)
  631. #define ERR_VLD8_BADLINK    (ERR_BASE-23)
  632. #define ERR_VLD8_NOCALLBACKALLOWED    (ERR_BASE-24)
  633. #define ERR_VLD8_ALLCBSERVERSBUSY    (ERR_BASE-25)
  634. #define ERR_VLD8_GUESTNOTALLOWED    (ERR_BASE-26)
  635. #define ERR_VLD8_SERVERISIMPOSTER    (ERR_BASE-27)
  636. #define ERR_VLD8_LOGINNOTENABLED    (ERR_BASE-28)
  637. #define ERR_REMOTEPORTALREADYEXISTS    (ERR_BASE-29)
  638. #define ERR_OPENNOTALLOWED    (ERR_BASE-30)
  639. #define ERR_NOUSERSANDGROUPS    (ERR_BASE-31)
  640. #define ERR_PORTSHUTDOWN    (ERR_BASE-32)
  641. #define ERR_PORTDOESNOTEXIST    (ERR_BASE-33)
  642. #define ERR_PWNEEDEDFORENABLE    (ERR_BASE-34)
  643. #define ERR_DAMAGED    (ERR_BASE-35)
  644. #define ERR_NETCONFIGCHANGED    (ERR_BASE-36)
  645. /* 2.0 and above only… */
  646. #define    ERR_NOSUPPORT_ATREMOTE    (ERR_BASE-37)
  647. #define ERR_CONFLICTING_REQUEST    (ERR_BASE-38)
  648. #define    ERR_VLD8_INVALIDAUTHMETHOD    (ERR_BASE-39)
  649. #define    ERR_VLD8_CONTINUE    (ERR_BASE-40)
  650. #define    ERR_PWCHANGECANCEL    (ERR_BASE-41)
  651. #define ERR_VLD8_MANUALPASSWORDREQUIRED    (ERR_BASE-50)
  652. #define ERR_END    ERR_VLD8_MANUALPASSWORDREQUIRED    /* must be last error */
  653. // ------------------------------------------------------------------------------
  654. // Connection Control Language Error Codes - CCL.h
  655. // ------------------------------------------------------------------------------
  656. #define    cclErr_BaseCode    -6000
  657. #define    cclErr_AbortMatchRead     cclErr_BaseCode        // internal error used to abort 
  658.                                     //match read
  659. #define    cclErr        (cclErr_BaseCode - 6)    // CCL error base
  660. #define cclErr_CloseError    (cclErr_BaseCode - 7)    // There is at least one script open
  661. #define cclErr_ScriptCancelled    (cclErr_BaseCode - 8)    // Script Canceled 
  662. #define    cclErr_TooManyLines    (cclErr_BaseCode - 9)    // Script contains too many 
  663.                                     // lines
  664. #define cclErr_ScriptTooBig    (cclErr_BaseCode - 10)    // Script contains too many 
  665.                                     // characters
  666. #define    cclErr_NotInitialized    (cclErr_BaseCode - 11)    // CCL has not been 
  667.                                     // initialized
  668. #define    cclErr_CancelInProgress    (cclErr_BaseCode - 12)    // Cancel in progress.
  669. #define    cclErr_PlayInProgress    (cclErr_BaseCode - 13)    // Play command already in 
  670.                                     // progress.
  671. #define    cclErr_ExitOK    (cclErr_BaseCode - 14)    // Exit with no error.
  672. #define    cclErr_BadLabel    (cclErr_BaseCode - 15)    // Label out of range.
  673. #define cclErr_BadCommand    (cclErr_BaseCode - 16)    // Bad command.
  674. #define    cclErr_EndOfScriptErr    (cclErr_BaseCode - 17)    // End of script reached, 
  675.                                     // expecting Exit.
  676. #define    cclErr_MatchStrIndxErr    (cclErr_BaseCode - 18)    // Match string index is out 
  677.                                 // of bounds.
  678. #define    cclErr_ModemErr    (cclErr_BaseCode - 19)    // Modem error, modem not 
  679.                                         // responding.
  680. #define    cclErr_NoDialTone    (cclErr_BaseCode - 20)    // No dial tone.
  681. #define    cclErr_NoCarrierErr    (cclErr_BaseCode - 21)    // No carrier.
  682. #define    cclErr_LineBusyErr    (cclErr_BaseCode - 22)    // Line busy.
  683. #define    cclErr_NoAnswerErr    (cclErr_BaseCode - 23)    // No answer.
  684. #define    cclErr_NoOriginateLabel    (cclErr_BaseCode - 24)    // No @ORIGINATE
  685. #define    cclErr_NoAnswerLabel    (cclErr_BaseCode - 25)    // No @ANSWER
  686. #define    cclErr_NoHangUpLabel    (cclErr_BaseCode - 26)    // No @HANGUP
  687. // ------------------------------------------------------------------------------
  688. // Link Tool Manager Error Codes - LTMInterface.h
  689. // ------------------------------------------------------------------------------
  690. #define    ERR_LTM_BASE    -5900        // base of errors for LTM
  691. #define ERR_LTM_LISTENER_ID_IN_USE    (ERR_LTM_BASE-1)    // Specified  Listener identifier is 
  692.                                     // in use
  693. #define ERR_LTM_NO_LISTENER    (ERR_LTM_BASE-2)    // Listener of specified type is not 
  694.                                     // available
  695. #define ERR_LTM_RESOURCE_NOT_REGISTERED (ERR_LTM_BASE-3)    // Listener of specified type is not 
  696.                                         // available
  697. #define ERR_LTM_PORT_NOT_CLAIMED    (ERR_LTM_BASE-4)    // claim request failed because to 
  698.                                     // port is busy
  699. #define ERR_LTM_COMMAND_NOT_ALLOWED    (ERR_LTM_BASE-5)    // LTM command not allowed on 
  700.                                     // specified port
  701. #define ERR_LTM_BAD_VERSION    (ERR_LTM_BASE-6)    // connect failed due to 
  702.                                     // incompatible LTM versions
  703. #define ERR_LTM_ARBITRATION_TIMEOUT    (ERR_LTM_BASE-7)    // Connection failed due to a time 
  704.                                     // out during the listener 
  705.                                     // arbitration
  706. #define ERR_LTM_KODE_NOT_FOUND    (ERR_LTM_BASE-8)    // kode resource not found in 
  707.                                     // specified file
  708. #define ERR_LTM_PORT_DISPOSED    (ERR_LTM_BASE-9)    // A Dispose Port call caused the 
  709.                                     // request to fail.
  710. #define ERR_LTM_RESOURCE_CLAIMED    (ERR_LTM_BASE-10)    // call failed because resource is 
  711.                                     // already claimed
  712. #define ERR_LTM_PORT_RESOURCES_CLAIMED    (ERR_LTM_BASE-11)    // call failed because the 
  713.                                             // port’s resources are 
  714.                                             // already claimed
  715. #define ERR_LTM_RESOURCE_NOT_CLAIMED    (ERR_LTM_BASE-12)    // call failed because the resource 
  716.                                         // was unclaimed
  717. #define ERR_LTM_PORT_RESOURCES_NOT_CLAIMED (ERR_LTM_BASE-13)    // The LTM port's resources
  718.                                             // are NOT claimed.
  719. #define ERR_LTM_PORT_UNCLAIMED    (ERR_LTM_BASE-14)    // LTM listen port unclaimed
  720. #define ERR_LTM_CONNECTION_REFUSED    (ERR_LTM_BASE-15)    // LTM listener refused connect
  721.                                     // request
  722. #define ERR_LTM_CLAIM_ABORTED    (ERR_LTM_BASE-16)    // LTM claim call aborted due to 
  723.                                     // LTM_ARB_CLAIM_CANCEL call
  724. #define ERR_LTM_END_OF_PORT_LIST    (ERR_LTM_BASE-17)    // End of open port list reached in 
  725.                                     // current port status session
  726. #define ERR_LTM_NOT_CONNECTED    (ERR_LTM_BASE-18)    // Not connected.
  727. #define ERR_LTM_CONNECTION_ABORTED    (ERR_LTM_BASE-19)    // Connection request aborted
  728. #define ERR_LTM_BAD_LENGTH    (ERR_LTM_BASE-20)    // Length of write request exceeds 
  729.                                     // maximum.
  730. #define ERR_LTM_BAD_PARAMETER    (ERR_LTM_BASE-21)    // Bad parameter.
  731. #define ERR_LTM_COMMAND_IN_PROGRESS    (ERR_LTM_BASE-22)    // Command already in progress.
  732. #define ERR_LTM_CONNECTED    (ERR_LTM_BASE-23)    // Connection established.
  733. #define    ERR_LTM_CONNECT_CANCELED     (ERR_LTM_BASE-24)    // Connection request canceled.
  734. #define    ERR_LTM_CONNECT_TIMEDOUT     (ERR_LTM_BASE-25)    // Connection time out.
  735. #define    ERR_LTM_NO_DEFAULTS     (ERR_LTM_BASE-26)    // Could not get default info...
  736. #define    ERR_LTM_GOOD_BYE    (ERR_LTM_BASE-27)    // The driver is going away in a 
  737.                                     // rude fashion
  738. dˇ ˇˇˇˇd
  739. d, Palatino
  740. .+H-Apple Remote Access API)ê External Reference Specification
  741. <°dONLNdHHäw(yH
  742. °dONLNdrwÄÅ+/®
  743. °dONLNdãH§ç(ùHApple
  744. °dONLNdççõê(óç 
  745. °dONLNd    ãê§=+
  746. Remote Access°dONLNd§HΩ
  747. (∂H'Application Programming Interface (API)°dONLNd?ΩH÷µ*!External Reference Specifications
  748. °dONLNdaÂHÛÍ* ENote: The Apple Remote Access API provides an application programming°dONLNdßÛH*Qinterface to the Remote Access Manager.  It supports calls to load and unload the°dONLNd˘H˛*KRemote Access Manager (RAM), create and terminate connections, retrieve the°dONLNdEH˘*Ocurrent RAM status, and to determine if a specified network address is local or°dONLNdïH+ˆ*Mremote.  Optionally, the Apple Remote Access API can display a user interface°dONLNd„+H9
  749. *Rshowing the process of a connection.  The parameters for the connect call can be a°dONLNd69HG*Oconnection document, created with the Remote Access application. The parameters°dONLNdÜGHU*Qof the connection, however, may not be specified out right when connecting to ARA°dONLNdÿUHc*X2.0.  These specifications also include how to tell if Apple Remote Access is installed,°dONLNd1cHq*Pand how to deal with the serial port when Apple Remote Access is in answer mode.
  750. °dONLNdÇHÏ*°BAlthough every attempt has been made to verify the accuracy of the°dONLNd≈H"*Iinformation presented, this document may contain errors and is subject to°dONLNd"H2g*-change.  ARA 2.0 features are not guaranteed.
  751. +H√1ˇ
  752. Ædˇ ˇˇˇˇd
  753. d, Palatino
  754. .+H-Apple Remote Access API)ê External Reference Specification
  755. °dONLNdHHX}(THGestalts
  756. °dONLNd    fHt
  757. *QWhen fully installed, Remote Access defines several new gestalt selectors.  Below°dONLNd[tHÇV*1are the new defines and explanation of their use.°dONLNdçãHôË*RTo see if serial port arbitration is installed, call _Gestalt using these defines.,
  758. Courier
  759.     °dONLNd‡£HÆ *#define gestaltArbitorAttr°dONLNd˛£DÆb)¸'arb '°dONLNd≠H∏(µH&#define gestaltSerialArbitrationExists°dONLNd-≠D∏I)¸0
  760. °dONLNd/≈H”ê(œH For example:
  761.     °dONLNd<”Hfiu*     OSErr io;°dONLNdF›HË`*
  762. 8// check to see if serial port arbitrating is installed…°dONLNdÁHÚâ*
  763.  
  764. long attribs;°dONLNdçÒH¸*
  765. +io = Gestalt(gestaltArbitorAttr, &attribs);°dONLNdπ˚Hø*
  766. Kif ( ((io == noErr) && (attribs & (1 << gestaltSerialArbitrationExists))) )°dONLNdH\*
  767.    {°dONLNd
  768. HÚ*
  769. "   // have serial port arbitration°dONLNd-H$\*
  770.    }°dONLNd2#H.\*
  771. else°dONLNd7-H8\*
  772.    {°dONLNd<7HBË*
  773.     // no serial port arbitration°dONLNd]AHL\*
  774.    }
  775. °dONLNdbUHcÂ*LMore information on serial port arbitration is discussed in a section below.°dONLNdØqHË*LTo see if Remote Access Connection Interface is available use these defines:
  776.     °dONLNd¸âHî„*#define gestaltRemoteAccessAttr°dONLNdâDîb)¸'strm'°dONLNd%ìHûÌ(õH!#define gestaltRemoteAccessExists°dONLNdIìDûI)¸0
  777. °dONLNdK±Hø˜(ªHMTo check if Remote Access support is available in the Alias Manager use these°dONLNdôøHÕs*defines:
  778.     °dONLNd¢◊H‚‘*#define gestaltAliasMgrAttr °dONLNd¡◊D‚b)¸'alis'°dONLNd»◊h‚˘)$// as defined in GestaltEqu.h°dONLNdÊ·HÏ.(ÈH.#define gestaltAliasMgrSupportsRemoteAppletalk°dONLNd·DÏI)¸1
  779. °dONLNdıHà(ˇH;To use ARA 2.0 features, call _Gestalt using these defines.
  780.     °dONLNdSH˜*##define gestaltRemoteAccessCallOnly°dONLNdyDI)¸1°dONLNd{h‡)$// checks for ARA client°dONLNdîH&˜(#H##define gestaltRemoteAccessMPServer°dONLNd∫D&I)¸2°dONLNdºh&)$#// checks for ARA multi-port server°dONLNd‡%H0Ë(-H #define gestaltRemoteAccessVers2°dONLNd%D0I)¸3°dONLNd%h0˛)$// checks for ARA 2.0 features
  781. °dONLNd$CHS’(OHSerial Port Arbitration
  782. °dONLNd<aHo*QWhen installed Remote Access provides serial port arbitration throught the Serial°dONLNdéoH}Ì*MPort Arbitrator tool.   All serial drivers registered with the Communications°dONLNd‹}Hãö*>Resource Manager are arbitrated by the Serial Port Arbitrator.°dONLNdôHߨ*ETo check to see if the Serial Port Arbitrator is installed, check the
  783.     °dONLNdd©H¥fi*gestaltSerialArbitrationExists
  784. °dONLNdÇßfiµ)ñ
  785.  flag of the 
  786.     °dONLNdè©¥u)=gestaltArbitorAttr
  787. °dONLNd°ßuµÊ)Z Gestalt selector  (see°dONLNdπµH√•(øHB“Gestalts” section for these defines and an example of this call).
  788. +H22ˇ ¥dˇ ˇˇˇˇd
  789. d, Palatino
  790. .+H-Apple Remote Access API)ê External Reference Specification
  791. °dONLNdVHd(`HTIf serial port arbitration is present, call OpenDriver when you want to use a serial°dONLNdUdHr
  792. *Tport.  If the driver requested is not open, OpenDriver will return a result of noErr°dONLNd™rHÄ*Rand the reference number of the driver.  If the driver requested is open (in use),°dONLNd˝ÄHé*!OpenDriver will return the error ,
  793. Courier
  794.     °dONLNdÇç/)∫    portInUse
  795. °dONLNd'Ä/é)-*.  When you are finished using the driver,°dONLNdRéHú˝(òHNcall CloseDriver.  OpenDriver and CloseDriver calls should always be balanced,°dONLNd¢úH™*Salthough the Serial Port Arbitrator will protect against multiple open/close calls.°dONLNd˜∏HΔ*TIf serial port arbitration is not present, do not use OpenDriver to determine if the°dONLNdLΔH‘Ú*Odriver is open.  It will return you a result of noErr and the reference number,°dONLNdú‘H‚ *Tallowing you access to a driver that another application is using.   To determine if°dONLNdÒ‚H *Qthe serial driver requested is open by another application, you must walk the DCE°dONLNdCH˛*T(Device Control Entry) unit table (see Device Driver chapter of Inside Macintosh vol°dONLNdò˛H W*II).°dONLNdùH(*VIt is important to use the new method if serial port arbitration is available.  Remote°dONLNdÙ(H6*WAccess, when set up for answering calls, is passively using a particular serial driver.°dONLNdM6HD*TIf you use the new method, the Serial Port Arbitrator will give up the passive claim°dONLNd¢DHR*Rand allow your OpenDriver call to return noErr.  Later, when you call CloseDriver,°dONLNdıRH`Ï*IRemote Access will again passively claim the port and setup the modem for°dONLNd?`HnÖ*
  796. answering.°dONLNdKwHÖ    *RBelow is a code example in C illustrating how to use serial port drivers under the°dONLNdûÖHìƒ*new and old methods:
  797.     °dONLNd≥ßH≤ª* #include <GestaltEqu.h>°dONLNdÀ±Hºß*
  798. #include <SysEqu.h>°dONLNdflªHΔ¨*
  799. #include <Devices.h>°dONLNdÙœH⁄¢*#include <stdio.h>°dONLNd„HÓœ*#define gestaltArbitorAttr °dONLNd%„ Ó>)ÿ'arb '°dONLNd,ÌH¯(ıH&#define gestaltSerialArbitrationExists°dONLNdSÌ ¯%)ÿ0°dONLNdU˜Hù(ˇH#define dRAMBased°dONLNdk˜ >)ÿ0x0040°dONLNdrH ì(    H#define dOpened°dONLNdÜ  >)ÿ0x0020°dONLNdçH (H%Boolean SerialArbitrationExists(void)°dONLNd≥H*M*
  800. {°dONLNd∂)Z4n+
  801. long°dONLNdª)~4´)$    response;°dONLNdΔ3Z>s(;ZOSErr°dONLNdÃ3~>í)$err;°dONLNd‘GZR;(OZ-err = Gestalt(gestaltArbitorAttr, &response);°dONLNdQZ\Ç*
  802. if (err)°dONLNd[lf≠+
  803.  
  804. return false;°dONLNdeZp|(mZ:return ((response >> gestaltSerialArbitrationExists) & 1);°dONLNdXoHzM(wH}
  805. +Hz3ˇ ædˇ ˇˇˇˇd
  806. d, Palatino
  807. .+H-Apple Remote Access API)ê External Reference Specification,
  808. Courier
  809.     °dONLNdRH](ZH*Boolean DriverIsOpen(StringPtr driverName)°dONLNd+\HgM*
  810. {°dONLNd.flq‰+$
  811. Boolean canOpen = false;°dONLNdHpl{⁄*
  812. Boolean match = false;°dONLNd`zlÖÖ*
  813. short°dONLNdfzêÖ¬)$
  814. index = 0;°dONLNdrÑlèÖ(ålshort°dONLNdxÑêèÆ)$count;°dONLNdÄélôû(ñl
  815. DCtlHandle°dONLNdãé¥ôÊ)H
  816. dceHandle;°dONLNdóòl£ô(†l    StringPtr°dONLNd°ò¥£‹)HnamePtr;°dONLNd´¢l≠û(™l
  817. DCtlHandle°dONLNd∂¢¥≠˙)H*theUnitTable;°dONLNd»∂l¡±(ælA// this is the low memory global containing the number of entries°dONLNd ¿lÀ–*
  818. // in the Unit Table°dONLNd" l’*
  819. count = *(short *)UnitNtryCnt;°dONLNdDfilÈ>**theUnitTable = *(DCtlHandle **)UTableBase;°dONLNdrÚl˝ *$while ( !match && (index < count)) {°dONLNdô¸êS+$
  820. '// get handle to a device control entry°dONLNd√ê0*
  821.  dceHandle = theUnitTable[index];°dONLNdÈê%‡*if (dceHandle) {°dONLNd˝$¥/ï+$
  822. -if (!( (**dceHandle).dCtlFlags & dRAMBased) )°dONLNd/.ÿ9“+$
  823. 2// RAM based drivers have a handle to their driver°dONLNdf8ÿCÕ*
  824. 1namePtr = (StringPtr)(**dceHandle).dCtlDriver+18;°dONLNdõB¥M»(J¥else°dONLNd§LÿW◊+$
  825. 3// ROM based drivers have a pointer to their driver°dONLNd‹Vÿa˙*
  826. :namePtr = (StringPtr) (*(DCtlPtr)dceHandle).dCtlDriver+18;°dONLNdj¥uö(r¥.// not case sensitive, diacritical marks count°dONLNdLt¥«*
  827. 7if (RelString(driverName, namePtr, false, true) == 0) {°dONLNdà~ÿâ+$
  828.  
  829. match = true;°dONLNdöàÿì    *
  830. =canOpen = ((**dceHandle).dCtlFlags & dOpened) ? true : false;°dONLNd€í¥ùπ(ö¥}°dONLNdflúêßï(§ê}°dONLNd„¶ê±∏*
  831. index++;°dONLNdÌ∞lªq(∏l}°dONLNd∫l≈∑*
  832. return canOpen;°dONLNdƒHœM(ÃH}°dONLNdÿH„ *Boolean CRMInstalled(void)°dONLNd‚HÌM*
  833. {°dONLNd Ïl˜Ä+$
  834. long°dONLNd%Ïê˜Ω)$    response;°dONLNd0ˆlÖ(˛lOSErr°dONLNd6ˆê§)$err;°dONLNd>
  835. l9(l)err = Gestalt(gestaltCRMAttr, &response);°dONLNdilî*
  836. if (err)°dONLNdtê)—+$
  837.  
  838. return false;°dONLNdÉ(l3M(0l-return ((response >> gestaltCRMPresent) & 1);°dONLNd±2H=M(:H}°dONLNd≥FHQf*Str255°dONLNd∫FlQ)$gDriverNames[] = {"\p.NoDrvr",°dONLNd‡P [\+¥
  839.   "\p.AOut",°dONLNdÙZ eW*
  840.   "\p.BIn",°dONLNdd o\*
  841.   "\p.BOut",°dONLNdn yk*
  842.   "\p.AppleCD",°dONLNd0x ÉW*
  843.   "\p.MPP",°dONLNdBÇ çf*
  844.   "\p.ASYC00",°dONLNdWå óR*
  845.  
  846.   "\p.AIn"°dONLNdhñ °/*
  847.  };
  848. (Òê4ˇÍdˇ ˇˇˇˇd
  849. d, Palatino
  850. .+H-Apple Remote Access API)ê External Reference Specification,
  851. Courier
  852.     °dONLNdHHSù(PH#define TEST_CALL°dONLNdRH]f*
  853. main()°dONLNd\HgM*
  854. {°dONLNdflqÖ+$
  855. OSErr°dONLNd"fêqÃ)$ err = noErr;°dONLNd0pl{Ö(xlshort°dONLNd6pê{ö)$i;°dONLNd:zlÖÖ(Çlshort°dONLNd@zêÖ«)$ numDrivers;°dONLNdOélô*(ñl&printf("Test of serial port stuff\n");°dONLNdwòl£À*
  856. if (CRMInstalled())°dONLNdç¢ê≠≠+$
  857. 9printf("Communication Resource Manager is installed.\n");°dONLNd»¨l∑(¥lif (SerialArbitrationExists())°dONLNdÈ∂ê¡N+$
  858. &printf("Serial Arbitration exists\n");°dONLNd H’ò(“H#ifdef TEST_CALL°dONLNd%‘lflk+$
  859. 3numDrivers = sizeof(gDriverNames) / sizeof(Str255);°dONLNdZfilÈ *
  860.  for (i = 0; i < numDrivers; i++)°dONLNd}ËêÛb+$
  861. *printf("DriverIsOpen(%#s)\treturned %s\n",°dONLNd≠Úÿ˝+H
  862. @gDriverNames[i], DriverIsOpen(gDriverNames[i])?"True ":"False");°dONLNdÓ¸Hf(H#endif°dONLNdıHò*#ifdef TEST_OPEN°dONLNdl%Ö+$
  863. short°dONLNd
  864. ê%≥)$refNum;°dONLNd.l9¯(6lif (!DriverIsOpen("\p.AIn"))°dONLNd58êCD+$
  865. $err = OpenDriver("\p.AIn", &refNum);°dONLNd[BlMî(Jlif (err)°dONLNdfLêWX+$
  866. (printf("OpenDriver returned %d\n", err);°dONLNdêVlaÓ(^lerr = CloseDriver(refNum);°dONLNd¨`lkî*
  867. if (err)°dONLNd∑jêu]+$
  868. )printf("CloseDriver returned %d\n", err);°dONLNd·tHf(|H#endif°dONLNdË~HâM*
  869. }
  870. (Òê5ˇdˇ ˇˇˇˇd
  871. d, Palatino
  872. .+H-Apple Remote Access API)ê External Reference Specification
  873. °dONLNdHHX‰(THApple Remote Access API°dONLNdfHvœ*Common Parameters
  874. °dONLNd*vHÑ*LThe TRemoteAccessParamBlock is a union of  all of the available Apple Remote°dONLNdwÑHí*LAccess API commands.  The TRemoteAccessParmHeader is a struct which consists°dONLNdƒíH† *Lof a DControlParamHeader followed by a DExtendedParam which is followed by a°dONLNd†HÆÛ*HDRemoteAccessParmHeader.  The extendedCode  is used to specify the Apple°dONLNdZÆHº*RRemote Access API  command wanted.  The resultStrPtr field returns a Pascal string°dONLNd≠ºH *Yto indicate what error occurred.  If you are not interested in the string, set this field°dONLNd Hÿ*Zto nil.  If you do pass a pointer however, it must point to a buffer of at least 256 bytes°dONLNdbÿHÊ*Vin length.  If the result of the call happens to be noErr, then the length byte of the°dONLNdπÊHÙ*Sstring will be zero.   Since this version of Remote Access only deals with the user°dONLNd
  875. ÙH*Rport, the parameter portGlobalsPtr should always be set to zero.  The csCode field°dONLNd`H*Gshould normally set to RAM_EXTENDED_CALL and the extendedType is set to°dONLNd®H*JREMOTEACCESSNAME.  These constants are defined in RemoteAccessInterface.h.,
  876. Courier
  877.     °dONLNdÛ,H7Ÿ*#define DControlParamHeader \°dONLNd6dA}+
  878. QElem°dONLNd6êA≥),*qLink;°dONLNd 6ÿAA)H// next queue entry \°dONLNd7@dK}(Hdshort°dONLNd=@êKÆ),qType;°dONLNdE@ÿK#)H// queue type \°dONLNdVJdU}(Rdshort°dONLNd\JêU≥),ioTrap;°dONLNddJÿU-)H// routine trap \°dONLNdwTd_s(\dPtr°dONLNd{Tê_¬),
  879. ioCmdAddr;°dONLNdÜTÿ_<)H// routine address \°dONLNdú^diá(fdProcPtr°dONLNd§^êi—),
  880. ioCompletion;°dONLNd≤^ÿiK)H// completion routine \°dONLNdÀhds}(pdOSErr°dONLNd—hêsΩ),    ioResult;°dONLNd€hÿs()H// result code \°dONLNdÌrd}x(zdlong°dONLNdÚrê}Ω),    userData;°dONLNd¸rÿ}P)H// for use by the user \°dONLNd|dá}(Ñdshort°dONLNd|êá≥),unused;°dONLNd$|ÿá-)H// unused field \°dONLNd7Üdë}(édshort°dONLNd=ÜêëΩ),    ioRefNum;°dONLNdGÜÿëd)H// driver reference number \°dONLNdeêdõ}(òdshort°dONLNdkêêõ≥),csCode;°dONLNdsêÿõå)H$// normally set to RAM_EXTENDED_CALL°dONLNdûöÿ•ë*
  881. %// for Apple Remote Access API  calls°dONLNdƒÆHπ¿(∂H#define DExtendedParam \°dONLNdfi∏d√Õ+
  882. DControlParamHeader \°dONLNdı¬dÕs*
  883. Ptr°dONLNd˘¬êÕ—),
  884. hReserved1; \°dONLNdÃd◊s(‘dPtr°dONLNd Ãê◊—),
  885. hReserved2; \°dONLNd÷d·s(fidPtr°dONLNd÷ê·€),resultStrPtr; \°dONLNd/÷Ù·À)d+// set to zero if result string is unwanted°dONLNd\‡dÎs(ËdPtr°dONLNd`‡êΗ),
  886. extendedType;°dONLNdo‡ÙÎÈ)d1// pointer to identifier string, normally set to (˨6// REMOTEACCESSNAME for Apple Remote Access API  calls°dONLNd›ÙHˇÌ(¸H!#define DRemoteAccessParmHeader \°dONLNd˛d    ¥+
  887. DExtendedParam \°dONLNdd}*
  888. short°dONLNdê—),
  889. extendedCode;°dONLNd'Ùû)d"// for use by extended call proc \°dONLNdKds(dPtr°dONLNdOê€),portGlobalsPtr;°dONLNd_ÙÓ)d2// pointer to globals for this port (0=userport) \°dONLNdí&H1fi(.Hstruct TRemoteAccessParmHeader°dONLNd±0H;M*
  890. {°dONLNd¥:dE◊+
  891. DRemoteAccessParmHeader°dONLNdÃDHOR(LH};°dONLNdœNHYÉ*
  892. ?typedef struct TRemoteAccessParmHeader TRemoteAccessParmHeader;°dONLNdbHmŸ*union TRemoteAccessParamBlock°dONLNd-lHwM*
  893. {°dONLNd0vdÅ◊+
  894. TRemoteAccessParmHeader°dONLNdHv¸Å)òHDR;°dONLNdNvDÅÄ)H // header pb°dONLNd\Ädã◊(àdTRemoteAccessParmHeader°dONLNdtĸã)òLOAD;°dONLNd{ÄDãv)H
  895. // load pb°dONLNdáädï◊(ídTRemoteAccessParmHeader°dONLNdüä¸ï)òUNLOAD;°dONLNdßäDïÄ)H // unload pb°dONLNdµîdü·(údTRemoteAccessConnectParam°dONLNdœî¸ü$)òCONNECT;°dONLNdÿîDüÖ)H
  896. // connect pb°dONLNdÁûd©ı(¶dTRemoteAccessDisconnectParam °dONLNd    û¸©3)ò DISCONNECT;°dONLNd    ûD©î)H// disconnect pb°dONLNd    #®d≥‹(∞dTRemoteAccessStatusParam°dONLNd    <®¸≥)òSTATUS;°dONLNd    D®D≥≠)H// get current status°dONLNd    [≤dΩÊ(∫dTRemoteAccessIsRemoteParms°dONLNd    v≤¸Ω))ò    ISREMOTE;°dONLNd    Ä≤DΩÈ)H!// check network address location°dONLNd    £ºd«Î(ƒdTRemoteAccessPasswordMunger°dONLNd    øº¸«$)òMUNGEPW;°dONLNd    »ºD«⁄)H// run password through munger°dONLNd    ËΔd—·(ŒdTRemoteAccessGetCodeHooks°dONLNd
  897. Δ¸—.)ò
  898. CODEHOOKS;°dONLNd
  899.  
  900. ΔD—Δ)H// get internal code hooks
  901. (Òê6ˇdˇ ˇˇˇˇd
  902. d, Palatino
  903. .+H-Apple Remote Access API)ê External Reference Specification,
  904. Courier
  905.     °dONLNdHdS·(Pd/* 2.0 and above only… */°dONLNdRd]√*
  906. T976SetOnlineNotify°dONLNd/Rÿ])t
  907. ONLINE_NOTIFY°dONLNd=R ]ß)H// used to toggle the state°dONLNd^\¥g(d¥// of notification°dONLNdrfdq•(nd
  908. unsigned char°dONLNdÅf¥q)P filler[256];°dONLNdèf q¿)l // set the minimum size of this (n–// parameter block°dONLNd pH{R(xH};°dONLNdÕzHÖ~*
  909. >typedef union TRemoteAccessParamBlock TRemoteAccessParamBlock;°dONLNd ÑHèj*
  910. :typedef TRemoteAccessParamBlock *TPRemoteAccessParamBlock;
  911. °dONLNdGöH™h*Load
  912. °dONLNdL™H∏*PThe load command is used to ensure that the Remote Access Manager is loaded into°dONLNdù∏HΔˆ*Lmemory and must be used before making a Connect call .  It uses the standard°dONLNdÍΔH‘*LTRemoteAccessParmBlock as the parameter block.  The example code below shows°dONLNd7‘H‚ *Nhow it works.  To use the MungePW command, it is not necessary to use the load°dONLNdÜ‚Hù*command first.
  913.     °dONLNdï˛H    Ú*"#include “RemoteAccessInterface.h”°dONLNd∏Hª*
  914. void LoadRemoteAccess()°dONLNd–HM*
  915. {°dONLNd”R'Ì+
  916.  
  917. TRemoteAccessParamBlock loadPB;°dONLNdˆ0R;*'loadPB.LOAD.csCode = RAM_EXTENDED_CALL;°dONLNd0 ;p)Œ// extended call°dONLNd0:REÌ(BRloadPB.LOAD.resultStrPtr = nil;°dONLNdP:¸EL)™// result string°dONLNdbDRO.(LR,loadPB.LOAD.extendedType = REMOTEACCESSNAME;°dONLNdèDDO£)Ú// to remote access°dONLNd§NRYB(VR0loadPB.LOAD.extendedCode = CmdRemoteAccess_Load;°dONLNd’NMYì)˚// try to load°dONLNdÂXRcÌ(`RPBRemoteAccess(&loadPB, false);°dONLNdX¸cV)™// issue sync call°dONLNdbRmœ(jRif (loadPB.LOAD.ioResult)°dONLNd5lZw˙+
  918.  ShowError(loadPB.LOAD.ioResult);°dONLNdVvHÅM(~H}
  919. °dONLNdXäHöw*Unload
  920. °dONLNd_öH®*LThe unload command is used to release the Remote Access Manager and free its°dONLNd¨®H∂*Lmemory.   It uses the standard TRemoteAccessParmBlock as the parameter block°dONLNd˘∂Hƒ*Rand can be issued immediately after making a Connect call.  This allows the Remote°dONLNdLƒH“*RAccess Manager to be unloaded as soon as an active connection is terminated with a°dONLNdü“H‡*Odisconnect, if no other clients have loaded Remote Access.  Below is an example°dONLNdÔ‡HÓâ* unload call.
  921.     °dONLNd¸¯HÚ*"#include “RemoteAccessInterface.h”°dONLNdH
  922. ≈*
  923. void UnloadRemoteAccess()°dONLNd9 HM*
  924. {°dONLNd<R!Ú+
  925.  
  926.  TRemoteAccessParmBlock unloadPB;°dONLNd`*R5…*K// unload the code (will not actually go away till this connection is done)°dONLNd≠4R?)*
  927. +unloadPB.UNLOAD.csCode = RAM_EXTENDED_CALL;°dONLNdŸ4D?î)Ú// extended call°dONLNdÎ>RI(FR#unloadPB.UNLOAD.resultStrPtr = nil;°dONLNd> Ip)Œ// result string°dONLNd!HRSB(PR0unloadPB.UNLOAD.extendedType = REMOTEACCESSNAME;°dONLNdRH^SΩ(P^// to remote access°dONLNdgRR]`(ZR6unloadPB.UNLOAD.extendedCode = CmdRemoteAccess_Unload;°dONLNdûRh]∏(Zh// try to unload°dONLNd∞\Rg˜(dR!PBRemoteAccess(&unloadPB, false);°dONLNd“\¸gV)™// issue sync call°dONLNdÊfRq„(nRif (unloadPB.UNLOAD.ioResult)°dONLNdp[{+    
  928. $ShowError(unloadPB.UNLOAD.ioResult);°dONLNd+zHÖM(ÇH}
  929. +Ho7ˇBdˇ ˇˇˇˇd
  930. d, Palatino
  931. .+H-Apple Remote Access API)ê External Reference Specification
  932. °dONLNdHHX}(THConnect
  933. °dONLNdXHf*UThis call is used to initiate an outgoing connection.  When you are connected in this°dONLNd^fHt*Rmode you will still retain access to your current network.  Network numbers are re°dONLNd∞ft(p-°dONLNd±tHÇ    (~HNmapped in a limited way in order to solve problems of network number conflicts°dONLNdÇHê*Qbetween the two machines being directly connected, thus ensuring they will always°dONLNdRêHû*Ybe accessible to each other.  Unfortunately, it is not possible to solve all of the other°dONLNd¨ûH¨*Tpossible conflicts due to the limited number of network numbers available.  In order°dONLNd¨H∫*Sto provide a method of ensuring access to all networks on the destination network a°dONLNdU∫H»*Rguaranteed access method is available.  When connected in this mode, you will lose°dONLNd®»H÷˝*Naccess to all services beyond those on the same single network number that the°dONLNd˜÷H‰ *Ucalling machine belongs to.  In order to notify clients of the AppleTalk stack that a°dONLNdM‰HÚ *Nnetwork will no longer be reachable we have created a new AppleTalk Transition°dONLNdúÚH¸*KQueue event.  (See Network Transition Events later in this document.)  When°dONLNdËH˘*Lconnecting the client passes in a TRAConnectInfoTemplate, or the FSSpec of a°dONLNd5H*Ldocument which contains the connect parameters.  The connect parameter block°dONLNdÇH**Rcontains the optionFlags field which specifies the connect options.  The flags are°dONLNd’*H8ï* shown below:,
  934. Courier
  935.     °dONLNd‚FHQª*// connect option flags°dONLNd˙PH[∂*
  936. #define kNSCanInteract°dONLNdP◊[    )è
  937. 0x00000001°dONLNdP[Ô)A+// User interaction (password prompt) is OK°dONLNdHZHe±(bH#define kNSShowStatus°dONLNd^Z◊e    )è
  938. 0x00000002°dONLNdiZe)A4// show the status of the connect or disconnect call°dONLNdûdHo (lH#define kNSConnectDocument°dONLNdπd◊o    )è
  939. 0x00000004°dONLNdƒdo)A4// connect using the specified document using FSSpec°dONLNd˘nHy∂(vH#define kNSPassWordSet°dONLNdn◊y    )è
  940. 0x00000010°dONLNdny)A3// use the specified password field when connecting°dONLNdWxÉ^*
  941. // by document°dONLNdfÇHçù(äH// 2.0 and above…°dONLNdxåHó∂*
  942. #define kNS2SavvyFlags°dONLNdèå◊ó    )è
  943. 0x40000000°dONLNdöåó)A2// Set to use the next 2 flags below for only ARA (î–// 2.0 aware applications.°dONLNdÌñH°¿(ûH#define kNSAR2Connection°dONLNdñ◊°    )è
  944. 0x00000020°dONLNdñ°Æ)A// connecting to a 2.0 server.°dONLNd1†H´(®H*#define kNSNotifyWhileConnected 0x00000040°dONLNd\† ´)ÿ2// display cute notification icon while connected.
  945. °dONLNdè∏HΔ˝(¬HOThe kNSCanInteract flag allows interaction with the user to get the password if°dONLNdflΔH‘*Unecessary or prompt the user to change their password if the server requires it.  The°dONLNd5‘H‚*OkNSShowStatus flag enables the connection status display.  The display is modal°dONLNdÖ‚H*Ndialog which updates with new messages as the connection progresses.  When the°dONLNd‘H˛Ò*IkNSConnectDocument flag is set, the Apple Remote Access API  will use the°dONLNd    ˛H *Pspecified ARA 2.0 document for the connect parameters (i.e. user name, password)°dONLNd    o H*Nof the TRAConnectInfoTemplate.  The document is specified by the FSSpec record°dONLNd    æH(*Kwhich contains vRefNum (volume reference number), parID (directory ID), and°dONLNd
  946.  
  947. (H6¸*Mname (pointer to Pascal style string containing the document name).  No other°dONLNd
  948. X6HDˇ*Lparameters need to be supplied.  The kNSPassWordSet flag overrides the saved°dONLNd
  949. •DHR*Lpassword when connecting by document or by PB and forces Apple Remote Access°dONLNd
  950. ÚRH`*UAPI  to use the passWord field in cleartext.  If the kNSPassWordSet flag is clear and°dONLNd H`Hn*Rthe passwordSaved flag is set, then the client must supply a munged password.  The°dONLNd õnH|˛*KkNS2SavvyFlags is set if using ARA 2.0 features.  The kNSAR2Connection flag°dONLNd Á|Hä*^indicates the connection is to a 2.0 server.  If this bit is not set, it is assumed that it is°dONLNd FäHò*Oa 1.0 connection.  The kNSNotifyWhileConnected flag will display a notification°dONLNd ñòH¶n*3icon on the Apple Menu while the user is connected.°dONLNd  ¥H¬„*LIn this release, the client may not connect by parameter block (PB). Use the°dONLNd
  951. ¬H–*IkNSConnectDocument flag to connect with a specified ARA 2.0 document. The
  952. +H%8ˇ8dˇ ˇˇˇˇd
  953. d, Palatino
  954. .+H-Apple Remote Access API)ê External Reference Specification
  955. °dONLNdHHV(RHWfields in the connectInfo record are discussed below.  They are filled by the specified°dONLNdXVHd*OARA 2.0 document.  Within this record is a version which is used by the connect°dONLNd®dHr*Xtemplate (currently set to 1).  The ltType parameter specifies the type of the link tool°dONLNdrHÄ    *Pthat will be used in this connection. The ARA 2.0 connect document specifies the°dONLNdRÄHé*Tlength and points to the address used in connecting by setting up  addressInfoLength°dONLNdßéHú*Vand addressInfoPtr.  The ltSpecificTemplatePtr is expected to point to the template of°dONLNd˛úH™*Tthe link tool specific parms.  An example of link tool specific parms might be items°dONLNdS™H∏*Tsuch as the serial port reference (.AIn, .AOut) that is used in the Modem Link Tool.°dONLNd©∏HΔÊ*KA userName is passed in that indicates the name of the user logging in.   A°dONLNdıΔH‘*ZpassWord is specified if the user is not logging in as a guest.  If the user wants to be a°dONLNdP‘H‚*Sguest, the guestLogin flag is set.   The connectReminderTimer is used if the caller°dONLNd§‚HÓ*Pwants to be reminded that a connection is in progress.  This field is set to the°dONLNdıH˛*Onumber of seconds between reminders, and can be set to zero if no reminders are°dONLNdE˛H *Mwanted.  If a connectReminderTimer is set you must set the connectOKWaitTimer°dONLNdì HÌ*Mthat indicates how long the reminder dialog will wait for OK to be hit before°dONLNd·H(ò*disconnecting.
  956. (Òê9ˇÊdˇ ˇˇˇˇd
  957. d, Palatino
  958. .+H-Apple Remote Access API)ê External Reference Specification,
  959. Courier
  960.     °dONLNdHHSŸ(PHstruct TRAConnectInfoTemplate°dONLNdRH]M*
  961. {°dONLNd!\Rg¿+
  962.  
  963. unsigned long version;°dONLNd8\ÿgU)Ü// version of this format°dONLNdSfRqª(nRunsigned long ltType;°dONLNdifÿq-)Ü// Link Tool type°dONLNd|pR{≈(xRlong addressInfoLength;°dONLNdîpÿ{å)Ü$// length of the address information°dONLNd∫zRÖ±(ÇRPtr addressInfoPtr;°dONLNdŒzÿÖÇ)Ü"// pointer to connect address info°dONLNdÚÑRèÌ(åRlong ltSpecificTemplateLength; °dONLNdѸèø)™'// length of the ltspecific information°dONLNd;éRô‘(ñRPtr ltSpecificTemplatePtr;°dONLNdVé¸ôø)™'// pointer to link tool specific params°dONLNdòR£(†R(unsigned char passWord[PASSWORDBUFSIZE];°dONLNd®ò £p)Œ// user password°dONLNd∫¢R≠ (™R%unsigned char userName[USERNAMESIZE];°dONLNd‡¢ ≠\)Œ // user name°dONLNdÔ¨R∑(¥R#unsigned long connectReminderTimer;°dONLNd¨ ∑˜)Œ+// value for connection reminder in seconds°dONLNd@∂R¡˜(æR!unsigned long connectOKWaitTimer;°dONLNdb∂¸¡ÿ)™,// how long to wait for OK on reminder timer°dONLNdê¿RÀ±(»RBoolean guestLogin;°dONLNd§¿ÿÀ_)Ü// try to log in as a guest°dONLNd¬ R’¿(“RBoolean passwordSaved;°dONLNdŸ ÿ’_)Ü// set if password is saved°dONLNd˜‘Rflœ(‹RBoolean guaranteedAccess;°dONLNd‘ÿfl√)Ü/// flag to guarantee access to servers internet°dONLNdAfiHÈR(ÊH};°dONLNdDËHÛy*
  964. =typedef struct TRAConnectInfoTemplate TRAConnectInfoTemplate;°dONLNdÇÚH˝`*
  965. 8typedef TRAConnectInfoTemplate *TPRAConnectInfoTemplate;°dONLNdªHË* struct TRemoteAccessConnectBlock°dONLNd‹HM*
  966. {°dONLNdflR%≈+
  967.  
  968. DRemoteAccessParmHeader°dONLNd¯$R/*
  969. #TRAConnectInfoTemplate connectInfo;°dONLNd$ /fi)Œ&// The connection information template°dONLNdD.R9‘(6Runsigned long optionFlags;°dONLNd_.¸9¶)™"// bit mapped connect option flags°dONLNdÑ8RC¢(@RFSSpec fileInfo;°dONLNdï8¥CY)b!// file info for connect document°dONLNd∑BHMR(JH};°dONLNd∫LHWó*
  970. Ctypedef struct TRemoteAccessConnectBlock TRemoteAccessConnectBlock;
  971. °dONLNd˛`Hne*1The following is an example connection procedure:
  972.     °dONLNd0zHÖÚ*"#include “RemoteAccessInterface.h”°dONLNdSÑHèò*
  973. void DoConnect()°dONLNddéHôM*
  974. {°dONLNdgòR£¸+
  975.  
  976. "TRemoteAccessParamBlock connectPB;°dONLNdã¢R≠à*
  977. >Str255 PathName = “MyHardDisk:Remote Access:Connect Document”;°dONLNdÀ∂R¡±*LoadRemoteAccess();°dONLNdfl∂ÿ¡x)Ü // Get the Remote Access Manager°dONLNd¿lÀô(»l    // loaded°dONLNd
  978.  R’3(“R-connectPB.CONNECT.csCode = RAM_EXTENDED_CALL;°dONLNd; D’î)Ú// extended call°dONLNdM‘Rfl (‹R%connectPB.CONNECT.resultStrPtr = nil;°dONLNds‘ fl¨)Œ// don’t want result strings°dONLNdëfiRÈV(ÊR4connectPB.CONNECT.extendedType = REMOTEACCESSNAME;  °dONLNdΔfihÈ«(Êh// to Remote Access°dONLNd€ËRÛy(R;connectPB.CONNECT.extendedCode = CmdRemoteAccess_DoConnect;°dONLNdËåÛÎ(å // connect command°dONLNd,ÚR˝(˙R'connectPB.CONNECT.portGlobalsPtr = nil;°dONLNdTÚ ˝Ñ)Œ// use the user port°dONLNdj¸R(R'connectPB.CONNECT.fileInfo.vRefNum = 0;°dONLNdí¸ ò)Œ// Use the full pathname°dONLNd¨R (R%connectPB.CONNECT.fileInfo.parID = 0;°dONLNd”RQ*
  979. 3strcpy(&PathName,&connectPB.CONNECT.fileInfo.name);°dONLNdh(h#// copy the string to fileInfo.name°dONLNd,$R/‚(,RP// Ask for password if needed, use connection document, & show connection status°dONLNd~.R9Ò*
  980. SconnectPB.CONNECT.optionFlags = kNSCanInteract | kNSConnectDocument | kNSShowStatus°dONLNd”8RC*
  981. )                         | kNS2SavvyFlags°dONLNd˝8DCΔ)Ú// Use the 2.0 flags below°dONLNd    BRM.(JR,                         | kNSAR2Connection °dONLNd    FBDM’)Ú// connection to a 2.0 server°dONLNd    dLHWQ(TH5                           | kNSNotifyWhileConnected;°dONLNd    öLhW(Th// displaying notification icon°dONLNd    ªVRa(^R$PBRemoteAccess(&connectPB, false);  °dONLNd    ‡V az)Œ// issue sync call°dONLNd    Ù`RkÌ(hRif (connectPB.CONNECT.ioResult)°dONLNd
  982. jRu*
  983. )  ShowError(connectPB.CONNECT.ioResult); °dONLNd
  984. ?jDuÓ)Ú"// Do Error reporting and recovery°dONLNd
  985. ctRª(|RUnloadRemoteAccess();°dONLNd
  986. ytÿd)Ü// Unload when disconnected.°dONLNd
  987. ñ~Hâé(ÜH} // DoConnect
  988. +Hk10ˇdˇ ˇˇˇˇd
  989. d, Palatino
  990. .+H-Apple Remote Access API)ê External Reference Specification
  991. °dONLNdHHXé(TH
  992. Disconnect
  993. °dONLNd XHf*RThe disconnect command is used to terminate an existing session or cancel one that°dONLNd^fHt*Uis being created.  If you only want to disconnect a session that was connected with a°dONLNd¥tHÇ*Rspecific parameter block you can do so by setting a pointer to the parameter block°dONLNdÇHê‡*Jused to issue the connect in abortOnlyThisPB.  If you want to disconnect a°dONLNdRêHû*Tconnection created by anyone, you set the abortOnlyThisPB field to zero.  If you are°dONLNdßûH¨*Udisconnecting an outgoing call, you pass zero in portGlobalsPtr.  Disconnecting ports°dONLNd˝¨H∫*Qother than the userport, is not supported in this version.  You should always set°dONLNdO∫H»*Kdisconnectin to zero.  The option kNSShowStatus will cause the Apple Remote°dONLNdõ»H÷õ*?Access API  to display the status dialog during the disconnect.,
  994. Courier
  995.     °dONLNd€‰HÔŸ*#define kNumWarnEntriesMax  5°dONLNd˘‰¸Ô¶)¥"// number of entries in warn array°dONLNdÓH˘˜(ˆH#struct TRemoteAccessDisconnectParam°dONLNd@¯HM*
  996. {°dONLNdCR
  997. ≈+
  998.  
  999. DRemoteAccessParmHeader°dONLNd\ RŸ*
  1000. unsigned long disconnectin;°dONLNdx ¸ú)™ // Note: Set this parameter to 0°dONLNdöR!(R)TPRemoteAccessParamBlock abortOnlyThisPB;°dONLNdƒ1!
  1001. )fl,// only abort a connection opened by this pb°dONLNdÚ R+)((R+unsigned long warnArr[kNumWarnEntriesMax]; °dONLNd 1+)fl.// set warn times here in seconds (zero all if°dONLNdO*l5∑(2l// no warnings)°dONLNdd4R?‘(<Runsigned long optionFlags;°dONLNd4¸?¶)™"// bit mapped connect option flags°dONLNd¢>HIR(FH};°dONLNd•HHSµ*
  1002. Itypedef struct TRemoteAccessDisconnectParam TRemoteAccessDisconnectParam;
  1003. °dONLNdÔ`Hn
  1004. *RThe following is an example of  a simple disconnect procedure.  It will disconnect°dONLNdBnH|Ú*any existing active connection.
  1005.     °dONLNdbäHïÚ*"#include “RemoteAccessInterface.h”°dONLNdÖîHüß*
  1006. void DoDisconnect()°dONLNdôûH©M*
  1007. {°dONLNdú®R≥ +
  1008.  
  1009. %TRemoteAccessParamBlock disconnectPB;°dONLNd√ºR«Ë*// set up the Remote Access PB°dONLNd„ΔR—Q*
  1010. 3disconnectPB.DISCONNECT.csCode = RAM_EXTENDED_CALL;°dONLNdΔh—∏(Œh// extended call°dONLNd*–R€)(ÿR+disconnectPB.DISCONNECT.resultStrPtr = nil;°dONLNdW–_€Î(ÿ_// don’t want result strings°dONLNdu⁄RÂj(‚R8disconnectPB.DISCONNECT.extendedType = REMOTEACCESSNAME;°dONLNdØ⁄∞Â(‚∞ // to Remote Access°dONLNd≈‰RÔ(ÏRYdisconnectPB.DISCONNECT.extendedCode = CmdRemoteAccess_Disconnect;  // disconnect command°dONLNd ÓR˘3*
  1011. -disconnectPB.DISCONNECT.portGlobalsPtr = nil;°dONLNdOÓ_˘õ(ˆ_ // user port°dONLNd]¯R8(R.disconnectPB.DISCONNECT.abortOnlyThisPB = nil;°dONLNdç¯_(_$// don't get tied to any specific pb°dONLNd≥R
  1012. e(
  1013. R7disconnectPB.DISCONNECT.optionFlags = 0| kNSShowStatus;°dONLNdÎå
  1014. (
  1015. å// show status while°dONLNd Hâ(H
  1016. disconnecting°dONLNdR! +
  1017.  
  1018. %PBRemoteAccess(&disconnectPB, false);°dONLNd6D!û)Ú// issue sync call°dONLNdJ R+ ((R%if (disconnectPB.DISCONNECT.ioResult)°dONLNdq*R5=*
  1019. /  ShowError(disconnectPB.DISCONNECT.ioResult); °dONLNd¢*_5    (2_"// Do Error reporting and recovery°dONLNd≈4H?M(<H}
  1020. +Hµ11ˇldˇ ˇˇˇˇd
  1021. d, Palatino
  1022. .+H-Apple Remote Access API)ê External Reference Specification
  1023. °dONLNdHHXÑ(THIsRemote
  1024. °dONLNd    XHf
  1025. *MThe "IsRemote" command is used to determine if a network address is remote or°dONLNdWfHt¯*Qlocal.  If the network is remote, the call will optionally return the information°dONLNd©tHÇ*Pnecessary to make the connection to the remote network. The parameter theAddress°dONLNd˙ÇHê*Rcontains the network address to be checked.   The format of theAddress is the same°dONLNdMêHûr*6as for the struct AddrBlock as defined in AppleTalk.h:°dONLNdÖ¨R∫D+
  1026. 'Bytes 3 & 2 (High Word): Network Number°dONLNdÆ∫R»À*Byte 1: Node Number°dONLNd√»R÷* Byte 0 (Low Byte): Socket Number°dONLNd‰‰HÚ(ÓHTThe optionFlags parameter is used for getting, or disposing, connection information.°dONLNd:ÚH˜* The following flags are defined:,
  1027. Courier
  1028.     °dONLNd]H‘*#define ctlir_getConnectInfo°dONLNdz¸)¥0x01°dONLNd Ú)$*// will get connect info if address remote°dONLNd™H#Ì( H!#define ctlir_disposeConnectInfo °dONLNdø#)¥0x02°dONLNd— # )$/// will dispose info in connectInfoPtr properly
  1029. °dONLNd0H>Ì(:HOIf the ctlir_getConnectInfo flag is set, and the network address is remote, the°dONLNdQ>HL‹*Jinformation necessary to create the remote connection is returned.  If the°dONLNdúLHZ*Uctlir_disposeConnectInfo flag is set, the connect information structure pointed to by°dONLNdÚZHh*(connectInfoPtr, is disposed of properly.°dONLNdvHÑ*QThe locationIsRemoteFlag parameter is a flag that is returned true if the network°dONLNdmÑHí*Oaddress is remote.  The connectInfoLength parameter indicates the length of the°dONLNdΩíH†*Sconnect information.  The connectInfoPtr is a pointer to the connection information°dONLNd†HÆÛ*Kfor connecting with the remote address.  These values are returned when the°dONLNd]ÆHº∏*Dnetwork address is remote, and the ctlir_getConnectInfo flag is set.
  1030.     °dONLNd§ H’Ì*!struct TRemoteAccessIsRemoteParms°dONLNdΔ‘HflM*
  1031. {°dONLNd…fiRÈ≈+
  1032.  
  1033. DRemoteAccessParmHeader°dONLNd‚ËRÛß*
  1034. long theAddress; °dONLNdˆ˸Ûú)™ // address that is to be checked°dONLNdÚR˝‘(˙Runsigned long optionFlags;°dONLNd3Ú¸˝°)™!// Set to ctlir_getConnectInfo or°dONLNdW¸l\(l0// ctlir_disposeConnectInfo, if zero only checks°dONLNdäl≠*
  1035.  
  1036. // theAddress°dONLNdôR„(RBoolean locationIsRemoteFlag;°dONLNd∑¸∞)™$// returns true if address is remote°dONLNd›R%≈("Rlong connectInfoLength;°dONLNdˆ¸%ó)™// length of the following data°dONLNd$R/(,R'TPRAConnectInfoTemplate connectInfoPtr;°dONLNd@$ /)Œ.// The connection information template pointer°dONLNdp.H9R(6H};°dONLNds8HC°*
  1037. Etypedef struct TRemoteAccessIsRemoteParms TRemoteAccessIsRemoteParms;
  1038. °dONLNdπPH`q*Status
  1039. °dONLNd¿`Hn˘*JThe status command is used to obtain information about Remote Access.  The°dONLNd nH|    *Minformation you can obtain is how long a connection has been active, how much°dONLNdY|Hä˙*Ktime remains in the connection, the name of the user that made an answering°dONLNd•äHò*Rconnection, the name of the computer you are connected to on a calling connection,°dONLNd¯òH¶*Tand the last message that was posted.  The statusBits parameter is used to determine°dONLNd    M¶H¥‹*Nif a connection is active, starting up, in the process of tearing down, if the°dONLNd    ú¥H¬¸*Oconnection is an answering or calling connection, if the computer is enabled to°dONLNd    Ï¬H–*Xreceive answer calls or if a disconnect is in progress. The following flags are defined:
  1040. +H%12ˇ“dˇ ˇˇˇˇd
  1041. d, Palatino
  1042. .+H-Apple Remote Access API)ê External Reference Specification,
  1043. Courier
  1044.     °dONLNdVHaÌ(^H!// bits passed back in statusBits°dONLNd"`Hk*
  1045. *#define CctlConnected           0x00000001°dONLNdM` kâ)ÿ// set when connected°dONLNdcjHu(rH*#define CctlAnswerEnable        0x00000004°dONLNdéj ufi)ÿ&// set when we are set to answer calls°dONLNdµtH(|H*#define CctlServerMode          0x00000008°dONLNd‡t ˜)ÿ+// set for answer mode, clear for call mode°dONLNd ~Hâ(ÜH*#define CctlConnectionAborting  0x00000010°dONLNd7~ â¿)ÿ // connection is being torn down°dONLNdXàHì(êH*#define CctlConnectInProg       0x00000020°dONLNdÉà ì˜)ÿ+// set when connection in progress or fully°dONLNd∑í ù\*
  1046. // connected°dONLNdƒúHß(§H*#define CctlDisconnectInStarted 0x00008000°dONLNdÔú ßfi)ÿ&// somebody has started a disconnectIn°dONLNd¶H±(ÆH*#define ctlAR2Connection        0x02000000°dONLNdA¶ ±)ÿ.// set when this connection is to a 2.0 server°dONLNdp∞Hª(∏H*#define ctlNotifyWhileConnected 0x04000000°dONLNdõ∞ ª)ÿ0// set when the user wants to be reminded while (∏d
  1047. // connected.°dONLNd‹∫H≈(¬H*#define ctlConnectedToMPS       0x08000000°dONLNd∫ ≈)ÿ0// set when client is connected to a multi-port (¬d    // server°dONLNdDƒHœ(ÃH*#define CctlMultiNodeReady      0x80000000°dONLNdoƒ œÚ)ÿ*// shows if we currently have a multinode (Ãà!// address to enable answer mode.
  1048. °dONLNd¿ÿHÊx(‚H7The following struct is used when making a status call:
  1049.     °dONLNd¯ÚH˝„*struct TRemoteAccessStatusParam°dONLNd¸HM*
  1050. {°dONLNdR≈+
  1051.  
  1052. DRemoteAccessParmHeader°dONLNd4Rœ*
  1053. unsigned long statusBits;°dONLNdNÿZ)Ü// bits for current status°dONLNdjR%fi("Runsigned long timeConnected;°dONLNdá¸%”)™+// number of seconds we have been connected°dONLNd¥$R/ (,Runsigned long  timeLeft;°dONLNdÕ$ÿ/¥)Ü,// number of seconds remaining in connection°dONLNd¸.l9‰(6l// (0xffffffff infinite)°dONLNd8RCŸ(@Runsigned char *userNamePtr;°dONLNd28¸CÏ)™0// returns user name, expects pointer to buffer (@d// of USERNAMESIZE if non nil°dONLNdÖBRM(JR#unsigned char  *connectedToNamePtr;°dONLNd©B!MÛ)œ*// returns name of where we connected to, (Jà0// expects pointer to buffer of USERNAMESIZE if (J
  1054. // non nil°dONLNdLRWÁ(TRQTPRemoteAccessParamBlock connectedByParamPtr; // a pointer to the parameter block°dONLNdlVla9+
  1055. )// "initiating" the connection if we are °dONLNdöV‘a(^‘ // connected°dONLNd®`Rk(hRWTPRemoteAccessParamBlock statusConnectedByParamPtr; // a pointer to the parameter block°dONLNdjluR+
  1056. .// "initiating" the connection when status was°dONLNd3tlô*
  1057.     // posted°dONLNd>~Râ(ÜR$unsigned char  *theLastStatusMsgPtr;°dONLNdc~!â⁄)œ%// expects pointer to buffer of size (Üà// MAXSTATUSMSGSIZE°dONLNd¢àRì¸(êR"unsigned char  *statusUserNamePtr;°dONLNd≈à!ìÓ)œ)// pointer to buffer of size USERNAMESIZE°dONLNdíRù±(öRlong  statuslttype;°dONLNdíÿù-)Ü// link tool type°dONLNdúRߟ(§Rlong  statusmsgOptionFlags;°dONLNd3ú¸ß°)™!// classification of message type°dONLNdV¶R±±(ÆRlong  statusMsgNum;°dONLNdj¶ÿ±Z)Ü// specific message number°dONLNdÜ∞Rª¿(∏Rlong  statusMsgSeqNum;°dONLNdù∞ÿªÕ)Ü1// pass in zero if always want status, otherwise (∏@/// use last value, if status is new, new number°dONLNd    ∫l≈≤(¬l// is returned°dONLNd    ƒRœ„(ÃRunsigned long  userSignature;°dONLNd    2ƒ¸œà)™// signature of port creator°dONLNd    PŒRŸ‘(÷Runsigned long  userRefCon;°dONLNd    kŒ¸Ÿy)™// refcon of port creator°dONLNd    ÖÿH„R(‡H};°dONLNd    à‚HÌç*
  1058. Atypedef struct TRemoteAccessStatusParam TRemoteAccessStatusParam;
  1059. °dONLNd     ˆH≈*EAn example status call that determines the state Remote Access is in.
  1060.     °dONLNd
  1061. HÚ*"#include “RemoteAccessInterface.h”°dONLNd
  1062. 3H#ò*
  1063. void GetStatus()°dONLNd
  1064. D"H-M*
  1065. {°dONLNd
  1066. G,Q7ˆ+    
  1067. !TRemoteAccessParamBlock statusPB;°dONLNd
  1068. j6QA*
  1069. (Str255 UserName,connectedTo,lastMessage;°dONLNd
  1070. î@QK°*
  1071. long statusBits;°dONLNd
  1072. ¶TQ_(*+statusPB.STATUS.csCode = RAM_EXTENDED_CALL;°dONLNd
  1073. “TD_î)Û// extended call°dONLNd
  1074. ‰^Qi(fQ#statusPB.STATUS.resultStrPtr = nil;°dONLNd ^ i)œ// put results here°dONLNd hQs
  1075. (pQ%statusPB.STATUS.portGlobalsPtr = nil;°dONLNd Ch sf)œ// do UserPort°dONLNd SrQ}A(zQ0statusPB.STATUS.extendedType = REMOTEACCESSNAME;°dONLNd Ñr_}•(z_// to Netshare°dONLNd î|Qái(ÑQ8statusPB.STATUS.extendedCode = CmdRemoteAccess_Status;  °dONLNd Õ|åá·(Ñå// status command°dONLNd ‡ÜQë(éQ(statusPB.STATUS.userNamePtr = &UserName;°dONLNd
  1076. êQõK*
  1077. 2statusPB.STATUS.connectedToNamePtr = &connectedTo;°dONLNd >öQ•P*
  1078. 3statusPB.STATUS.theLastStatusMsgPtr = &lastMessage;°dONLNd s§QØ*
  1079. (statusPB.STATUS.statusUserNamePtr = nil;°dONLNd ùÆQπ*
  1080. $statusPB.STATUS.statusMsgSeqNum = 0;°dONLNd ƒ∏Q√ˆ*
  1081. !PBRemoteAccess(&statusPB, false);°dONLNd Á¬QÕ‚*
  1082. if (statusPB.STATUS.ioResult)
  1083. +?'13ˇ"dˇ ˇˇˇˇd
  1084. d, Palatino
  1085. .+H-Apple Remote Access API)ê External Reference Specification,
  1086. Courier
  1087.     °dONLNdHQS[(PQ  °dONLNdHcS)%ShowError(statusPB.STATUS.ioResult); °dONLNd)HDSÓ)·"// Do Error reporting and recovery°dONLNdMRQ]e(ZQelse°dONLNdS\QgV*
  1088. {°dONLNdXfcq!+
  1089. &// now decode the flag bits into words°dONLNdÇpc{+*
  1090. (statusBits = statusPB.STATUS.statusBits;°dONLNdÆzcÖ*
  1091.  if (statusBits & CctlServerMode)°dONLNd”Ñlè+    
  1092. printf("Answer connection\n");°dONLNdıécô˛(ñcif (statusBits & CctlConnected)°dONLNdòl£+    
  1093. printf("Calling connection\n");°dONLNd<¢c≠+(™c(if (statusBits & CctlConnectionAborting)°dONLNdi¨l∑+    
  1094. printf("Cancel in progress\n");°dONLNdå∂c¡
  1095. (æc"if (statusBits & CctlAnswerEnable)°dONLNd≥¿lÀ*+    
  1096. &printf("Waiting for incoming call\n");°dONLNd› c’(“c#if (statusBits & CctlConnectInProg)°dONLNd‘lfl+    
  1097. #printf("Connection in progress\n");°dONLNd*fiRÈW(ÊR}°dONLNd,ËHÛé(H} // GetStatus
  1098. °dONLNd;H"›*.GetUserPortGlobalsPtr
  1099. °dONLNdQ"H0*TIn order to make the RAM Status call on a machine that is setup to answer calls, you°dONLNd¶0H>*Wmust first make the GetUserPortGlobalsPtr call to retrieve a pointer to the globals for°dONLNd˛>HLí*the user port.°dONLNd
  1100. ZHh„*FThe Apple Remote Access (ARA)  Personal software supports dial-out and°dONLNdThHv
  1101. *Qanswering capabilities through a single port called the “user” port (the modem or°dONLNd¶vHÑ*Pprinter port on your Mac). This means that when you setup your machine to answer°dONLNd˜ÑHíÁ*Lcalls, you can answer only one call at a time on the user port. However, the°dONLNdDíH†*Punderlying ARA architecture was designed so that multiple ports may be supported°dONLNdï†HÆ˚*"(in a dial-in server for example).°dONLNd∏ºH *MWhen you dial-out on your Mac and establish an ARA connection, ARA internally°dONLNd Hÿ*Xallocates the data structures for the user port - but not until a connection is actually°dONLNd_ÿHʆ*@made. This is why, for example, the Status call will return the 
  1102.     °dONLNdü€†‰∑(‚†-5833°dONLNd•ÈHÚæ(HERR_PORTDOESNOTEXIST
  1103. °dONLNdπÊæÙÊ)v7 error on the originating machine if there is no active°dONLNdÒÙH(˛HRconnection. Once a connection has been made on a machine that is the originator of°dONLNdDH*Wthe connection, the Status call should return no error, because the data structures for°dONLNdúHˆ* the port will have been created.°dONLNdΩ,H:¯*MWhen you make the Status call on a machine that is setup to answer calls (the°dONLNd :HH*Tanswer calls box is checked in the Remote Access Setup control panel), you will find°dONLNd`HHV…*that you always get the 
  1104.     °dONLNdxK…TX)Å-5833 ERR_PORTDOESNOTEXIST
  1105. °dONLNdíHXV )è# error. The reason for this is that°dONLNd∂VHd‚(`HHwhen ARA is in answer mode it needs to be able to uniquely identify each°dONLNdˇdHrÛ*Mconnection with a separate portGlobalsPtr, because in the future there may be°dONLNdMrHÄÎ*Isupport for more than one connection on a single machine. Therefore, on a°dONLNdóÄHé*Umachine that is setup to answer calls, you must first retrieve the portGlobalsPtr for°dONLNdÌéHú˜*Othe user port before the Status call can be made. This is accomplished with the°dONLNd    =úH™†*?GetUserPortGlobalsPtr call. This call makes use of the familiar°dONLNd    }™H∏*PTRemoteAccessParmHeader structure.  The pointer to the port globals for the user°dONLNd    Œ∏HΔ*Vport is returned in the portGlobalsPtr field upon completion of the call. Here are the
  1106. +H/14ˇ,dˇ ˇˇˇˇd
  1107. d, Palatino
  1108. .+H-Apple Remote Access API)ê External Reference Specification
  1109. °dONLNdHHVˆ(RH"data structures used by this call:°dONLNd#fHt¶*The fields in the 
  1110.     °dONLNd5i¶r)^TRemoteAccessParmHeader
  1111. °dONLNdLftë)n structure used for the 
  1112.     °dONLNddiërÔ)}GetUserPortGlobalsPtr
  1113. °dONLNdyfÔt)^ call to°dONLNdÇtHÇb(~H1the Remote Access Manager are defined as follows:,
  1114. Courier
  1115.     °dONLNd¥íHùR*->°dONLNd∑ílùv)$12°dONLNd∫íêùÃ)$ ioCompletion°dONLNd«íÿùÏ)Hlong°dONLNdÃí¸ùç)$pointer to completion routine°dONLNdÍúHßR(§H<-°dONLNdÌúlßv)$16°dONLNdúêß∏)$ioResult°dONLNd˘úÿßÏ)Hword°dONLNd˛ú¸ß3)$ result code°dONLNd
  1116. ¶H±R(ÆH->°dONLNd
  1117. ¶l±v)$20°dONLNd¶ê±∏)$userData°dONLNd¶ÿ±Ï)Hlong°dONLNd¶¸±[)$for use by the user°dONLNd2∞HªR(∏H->°dONLNd5∞lªv)$26°dONLNd8∞êª∏)$ioRefNum°dONLNdA∞ÿªÏ)Hword°dONLNdF∞¸ªo)$driver reference number°dONLNd^∫H≈R(¬H->°dONLNda∫l≈v)$28°dONLNdd∫ê≈Æ)$csCode°dONLNdl∫ÿ≈Ï)Hword°dONLNdq∫¸≈Q)$call command code°dONLNdɃHœR(ÃH->°dONLNd܃lœv)$40°dONLNdâƒêœÃ)$ extendedType°dONLNdñƒÿœÏ)Hlong°dONLNdõƒ¸œà)$pointer to identifier string°dONLNd∏ŒHŸR(÷H->°dONLNdªŒlŸv)$42°dONLNdæŒêŸÃ)$ extendedCode°dONLNdÀŒÿŸÏ)Hword°dONLNd–Œ¸Ÿ¶)$"for use by extended call procedure°dONLNdÛÿH„W(‡H<->°dONLNd˜ÿl„v)$44°dONLNd˙ÿê„Ô)$portGlobalsPtr long°dONLNdÿ¸„ˆ)l2pointer to globals for this port (0 = return user (‡
  1118. port globals)
  1119. °dONLNdVÚH˛(¸HSHere are the detailed descriptions of the parameter block fields used by this call:
  1120.     °dONLNd™HÑ* ioCompletion°dONLNd∑ê&)Hpointer to completion routine.°dONLNd÷H%p("HioResult°dONLNdflê%5)H!result code returned by the call.°dONLNd$H/p(,HuserData°dONLNd
  1121. $ê/&)Huser data for use by the user.°dONLNd).H9p(6HioRefNum°dONLNd2.ê9)Hdriver reference number.°dONLNdK8HCf(@HcsCode°dONLNdR8lC\)$0command code, normally set to RAM_EXTENDED_CALL.°dONLNdÉBHMÑ(JH extendedType°dONLNdêBêM:)H"should be set to REMOTEACCESSNAME.°dONLNd≥LHWÑ(TH extendedCode°dONLNd¿LêWô)H5set to 54 to indicate the GetUserPortGlobalsPtr call.°dONLNdˆVHaé(^HportGlobalsPtr°dONLNdV£a)[Jreturns a pointer to the globals for the port. On input pass 0 to indicate°dONLNdT`£k>*
  1122. you want the user port globals.
  1123. °dONLNdtzHà[(ÑH2The following result codes can be returned by the 
  1124.     °dONLNd¶}[Üπ(Ñ[GetUserPortGlobalsPtr
  1125. °dONLNdªzπà“)^ call:
  1126.     °dONLNd¬òH£a(†HnoErr°dONLNd…òê£ï)H0°dONLNdÀò££–)    no error.°dONLNd’¢H≠¨(™HERR_PORTDOESNOTEXIST°dONLNdÍ¢¥≠Õ)l-5833°dONLNd¢ÿ≠<)$port does not exist.°dONLNd¨H∑ò(¥HERR_PORTSHUTDOWN°dONLNd¨¥∑Õ)l-5832°dONLNd¨ÿ∑F)$port is shutting down.
  1127. °dONLNd4ΔH‘}(–H5The following is an example of how you would use the 
  1128.     °dONLNdi…}“€(–}GetUserPortGlobalsPtr
  1129. °dONLNd~Δ€‘)^  call prior°dONLNdä‘H‚ç(fiH to making a 
  1130.     °dONLNdñ◊燶)EStatus
  1131. °dONLNdú‘¶‚ø) call.
  1132.     °dONLNd£ÚH˝p(˙H#include°dONLNd¨Úê˝
  1133. )H"RemoteAccessInterface.h"°dONLNdΔHf(HStr255°dONLNdÕlû)$
  1134. ResultStr;°dONLNdÿHf(HStr255°dONLNdfllô)$    UserName;°dONLNdÈH%f("HStr255°dONLNdl%®)$ LastMessage;°dONLNd˝$H/f(,HStr255°dONLNd$l/®)$ ConnectedTo;°dONLNd>HI8(FH0#define CmdRemoteAccess_GetUserPortGlobalsPtr 54°dONLNdBRH]ì*void DoStatus()°dONLNdR\HgM*
  1135. {°dONLNdUfHqª*
  1136. TRemoteAccessParamBlock°dONLNdmfÿqÁ)êpb;°dONLNdszHÖ.(ÇH.  /* Ask LTM driver for PortGlobals address */°dONLNd§éHô¸*$  pb.HDR.csCode = RAM_EXTENDED_CALL;°dONLNd éDô£)¸/* extended call */°dONLNdfiòH£.(†H.  pb.HDR.extendedType = (Ptr)REMOTEACCESSNAME;°dONLNd
  1137. òD£ô)¸/* to Netshare */°dONLNd¢H≠
  1138. (™HZ  pb.HDR.extendedCode = CmdRemoteAccess_GetUserPortGlobalsPtr; /* get user port globals */°dONLNdz¨H∑„*
  1139.   pb.HDR.portGlobalsPtr = nil; °dONLNdú¨D∑Ó)¸"/* 0 = return user port globals */°dONLNdø∂H¡„(æH  PBRemoteAccess( &pb, false );°dONLNdfl¿HÀ„*
  1140.   if (pb.HDR.ioResult != noErr)
  1141. +H)15ˇ dˇ ˇˇˇˇd
  1142. d, Palatino
  1143. .+H-Apple Remote Access API)ê External Reference Specification,
  1144. Courier
  1145.     °dONLNdHHSÌ(PH!    HandleError(pb.HDR.ioResult);°dONLNd"RH]f*
  1146.   else°dONLNd)\HgW*
  1147.   {°dONLNd-pH{„*    /* Issue ARA Status Call */°dONLNdOÑHè±*    ResultStr[0] = 0;°dONLNdeéHô)*
  1148. -    pb.STATUS.resultStrPtr = (Ptr)ResultStr; °dONLNdìéDô≤)¸/* put results here */°dONLNd™òH£Q(†H5    pb.STATUS.extendedCode = CmdRemoteAccess_Status; °dONLNd‡òh£Ã(†h/* status command */°dONLNdı¢H≠(™H%    pb.STATUS.userNamePtr = UserName;°dONLNd¨H∑3*
  1149. /    pb.STATUS.connectedToNamePtr = ConnectedTo;°dONLNdK∂H¡8*
  1150. 0    pb.STATUS.theLastStatusMsgPtr = LastMessage;°dONLNd|¿HÀ¸*
  1151. $    pb.STATUS.statusUserNamePtr = 0;°dONLNd° H’Ú*
  1152. "    pb.STATUS.statusMsgSeqNum = 0;°dONLNdƒ‘HflÌ*
  1153. !    PBRemoteAccess( &pb, false );°dONLNdÊfiHȸ*
  1154. $    if (pb.STATUS.ioResult != noErr)°dONLNd ËHÛ*
  1155. &      HandleError(pb.STATUS.ioResult);°dONLNd2¸HW*  }°dONLNd6HM*
  1156. }
  1157. °dONLNd8H,* Thus, to make sure that the RAM 
  1158.     °dONLNdX!*)æStatus
  1159. °dONLNd^,)- call will work on machines that are setup to°dONLNdå,H:>(6H.answer calls, you will need to first make the 
  1160.     °dONLNd∫/>8ú)ˆGetUserPortGlobalsPtr
  1161. °dONLNdœ,ú:Ô)^ call so that the°dONLNd·:HHÌ(DHHRemote Access Manager knows which port to return status information for.
  1162. °dONLNd*hHxã*0MungePW
  1163. °dONLNd2xHÜ*MThe MungePW command is used to encrypt a password to be stored in a document.°dONLNdÅÜHî*ONormally, when connecting by document, it is not necessary to use this command,°dONLNd—îH¢*Rsince the password in a document is stored in encrypted format.   It uses a struct°dONLNd$¢H∞*ITRemoteAccessPasswordMunger with the inputs username pointer and password°dONLNdn∞Hæ*Rpointer.  The reserved field should always be set to zero.  The munged password is°dONLNd¡æHÃŒ*return in the data buffer
  1164. °dONLNd⁄øŒÀ–)Ü 
  1165. °dONLNd€æ–Ãf)pointed to by passWordPtr.
  1166. °dONLNdıøfÀj)ñ  
  1167. °dONLNd˜æjÃ)It is not necessary to call the°dONLNdÃH⁄(÷HELoad command before using MungePW.  The maximum username and password°dONLNd]⁄HË•*?lengths are defined in the RemoteAccessInterface.h header file.
  1168.     °dONLNdùÚH˝Ú*"struct TRemoteAccessPasswordMunger°dONLNd¿¸HM*
  1169. {°dONLNd√R≈+
  1170.  
  1171. DRemoteAccessParmHeader°dONLNd‹RŸ*
  1172. unsigned char *userNamePtr;°dONLNd¯¸ç)™// pointer to username string°dONLNdR%Ÿ("Runsigned char *passWordPtr;°dONLNd3¸%L)™// user password°dONLNdE$R/ (,Runsigned short reserved;°dONLNd_$¸/[)™// must set to zero°dONLNds.H9R(6H};°dONLNdv8HC´*
  1173. Gtypedef struct TRemoteAccessPasswordMunger TRemoteAccessPasswordMunger;
  1174. °dONLNdæLHZ˜*LBelow is an example routine that calls and gets the password in *passWordPtr°dONLNd ZHhz*munged.,2fAppleGaramond Lt2f°dONLNdsHÅJ* 
  1175.     °dONLNdvJÅÙ)"#include “RemoteAccessInterface.h”°dONLNd7ÄHã(àH&void MungePassword(UserName, PassWord)°dONLNd^äHï˜*
  1176. #unsigned char *UserName, *PassWord;°dONLNdÇîHüM*
  1177. {°dONLNdÖûR©+
  1178.  
  1179. $TRemoteAccessPasswordMunger mungePB;°dONLNd≠≤RΩ)*+mungePB.MUNGEPW.csCode = RAM_EXTENDED_CALL;°dONLNdŸ≤DΩô)Ú // extended call°dONLNdϺR«(ƒR#mungePB.MUNGEPW.resultStrPtr = nil;°dONLNdºD«ô)Ú // result string°dONLNd$ΔR—¶(ŒRDmungePB.MUNGEPW.extendedType = REMOTEACCESSNAME; // to remote access
  1180. +>#16ˇÇdˇ ˇˇˇˇd
  1181. d, Palatino
  1182. .+H-Apple Remote Access API)ê External Reference Specification,
  1183. Courier
  1184.     °dONLNdHRSà(PR>mungePB.MUNGEPW.extendedCode = CmdRemoteAccess_PassWordMunger;°dONLNd@RR]t*
  1185. :mungePB.MUNGEPW.userNamePtr = (unsigned char *) &UserName;°dONLNd|\Rgt*
  1186. :mungePB.MUNGEPW.passWordPtr = (unisgned char *) &password;°dONLNd∏fRqÚ*
  1187.  PBRemoteAccess(&mungePB, false);°dONLNdŸf¸qV)™// issue sync call°dONLNdÔpl{H(xl,// and encrypted the eight bytes in password°dONLNdÑRè„(åRif (mungePB.MUNGEPW.ioResult)°dONLNd=é[ô+    
  1188. $ShowError(mungePB.MUNGEPW.ioResult);°dONLNdd¢H≠¢(™H} // MungePassword
  1189. °dONLNdw∂HΔ´* GetCodeHooks
  1190. °dONLNdÑΔH‘fl*DThe GetCodeHooks command is used to return a pointer to the remapper°dONLNd…‘H‚*Uprocedure.  This routine can then be called to do special remappings for applications°dONLNd‚H*Wpassing network addresses as part of their data.  The call can be made with the clients°dONLNdwH˛*Lnetwork number and the node number and this routine will return the remapped°dONLNdƒ˛H å* equivalents.
  1191.     °dONLNd—H!Ë* struct TRemoteAccessGetCodeHooks°dONLNdÚ H+M*
  1192. {°dONLNdı*R5≈+
  1193.  
  1194. DRemoteAccessParmHeader°dONLNd4R?„*
  1195. RemmaperProcPtr remapperProc;°dONLNd,4¸?ú)™ // quick vector to remapper code°dONLNdM>HIR(FH};°dONLNdPHHSó*
  1196. Ctypedef struct TRemoteAccessGetCodeHooks TRemoteAccessGetCodeHooks;
  1197. °dONLNdî\Hjr*8The routine returned by this call is defined as follows:
  1198.     °dONLNdÕtH*Xpascal void DoRemapper(unsigned long whereNet, unsigned long incomingFlag, unsigned long°dONLNd&~HâÉ*
  1199. ?sourceSwapFlag, unsigned short *theNet, unsigned char *theNode),2hAppleGaramond Bd2h°dONLNdhíHús*
  1200. whereNet->°dONLNdrísù)+U This value has the net where this packet just came from or is going to, it is needed°dONLNd»úHßQ(§H5to determine if any remapping should even take place.2h°dONLNd˛∞H∫Ä*incomingFlag->°dONLNd ∞΍)8< Set to true if data is incoming, false if data is outgoing.2h°dONLNdIƒHŒà(ÃHsourceSwapFlag->°dONLNdYƒàœ    )@M Set to true if a source style swap is to be used.  A source style swap means°dONLNdߌHŸ(÷HYthat we do remappings based on the address being a source address. If this flag is false,°dONLNdÿH„Ì*
  1201. !destination style swaps are done.2h°dONLNd#ÏHˆi*theNet->°dONLNd+Ïi˜ö)!= Pointer to unsigned short containing the net to be remapped.2h°dONLNdiH
  1202. n(H    theNode->°dONLNdrn ü)&= Pointer to unsigned char containing the node to be remapped.,2fAppleGaramond Lt2f
  1203. °dONLNd∞HJ(H 
  1204.     °dONLNd±JÙ)"#include “RemoteAccessInterface.h”°dONLNd‘H)é(&HTestRemapper()°dONLNd„(H3M*
  1205. {°dONLNdÊ2R=+
  1206.  
  1207. (TRemoteAccessParamBlock  getcodehooksPB;°dONLNd<RG∂*
  1208. unsigned short rNet;°dONLNd&FRQ∂*
  1209. unsigned char rNode;°dONLNd<PR[ù*
  1210. ulong whereNet;°dONLNdLdHo›(lHQ  getcodehooksPB.CODEHOOKS.csCode = RAM_EXTENDED_CALL;        /* extended call */°dONLNdûnHyÿ*
  1211. P  getcodehooksPB.CODEHOOKS.portGlobalsPtr = nil;              /* do UserPort  */°dONLNdÔxHÉÏ*
  1212. T  getcodehooksPB.CODEHOOKS.extendedType = (Ptr)REMOTEACCESSNAME;  /* to Netshare  */°dONLNdDÇHç*
  1213. [  getcodehooksPB.CODEHOOKS.extendedCode = CmdRemoteAccess_GetCodeHooks; /* GetCodeHooks */ (ä /*command */°dONLNd¥åHó(îH+  PBRemoteAccess( &getcodehooksPB, false );°dONLNd‡ñH°=*
  1214. 1  if (getcodehooksPB.CODEHOOKS.ioResult == noErr)°dONLNd    †H´W*
  1215.   {°dONLNd    ™HµW*
  1216.    °dONLNd    ™lµ)$/* address we want remapped */°dONLNd    9¥Høò(ºH       rNet = 0;°dONLNd    JæH…¢*
  1217.        rNode = 51;
  1218. +H+17ˇ‘dˇ ˇˇˇˇd
  1219. d, Palatino
  1220. .+H-Apple Remote Access API)ê External Reference Specification,
  1221. Courier
  1222.     °dONLNdHHSª(PH       whereNet = 2200;°dONLNdRH]ò*
  1223.                 °dONLNd1\Rg
  1224. +
  1225.  
  1226. X(*getcodehooksPB.CODEHOOKS.remapperProc)(whereNet,false,true,(uPt r)&rNet,(uPtr)&rNode);°dONLNdépR{W*}°dONLNdêzHÖM(ÇH}
  1227. (Òê18ˇ,dˇ ˇˇˇˇd
  1228. d, Palatino
  1229. .+H-Apple Remote Access API)ê External Reference Specification
  1230. °dONLNdHHXÙ(THNetwork Transition Events
  1231. °dONLNdXHf*MNetwork transition events are generated by Remote Access to inform interested°dONLNdhfHt*Rclients that network connectivity has changed.  The type of change is indicated by°dONLNdªtHÇ*Xthe newConnectivity flag.  If this flag is true, new connectivity is being added (i.e. a°dONLNdÇHê*Sconnection to a new internet has taken place).  In this case, all network addresses°dONLNdhêHû*Vwill be returned as reachable.  If the newConnectivity flag is false, certain networks°dONLNdøûH¨*Pare no longer reachable.  Since Remote Access is connection based and internally°dONLNd¨H∫*Qfunctions much like a router it has knowledge of where a specific network exists.°dONLNdc∫H»*PRemote Access can take advantage of that knowledge during a disconnect to inform°dONLNd¥»H÷    *QAppleTalk clients that a network is no longer reachable.  This information can be°dONLNd÷H‰Ò*Kused by the AppleTalk client to age out connections immediately rather than°dONLNdR‰HÚ*Uwaiting a potentially long period of time before discovering that the other end is no°dONLNd®ÚH¶*longer reachable.°dONLNd∫H˘*KWhen Remote Access is disconnecting, it will generate a "Network Transition°dONLNdH*ˆ*KEvent (theEvent=5)" through the AppleTalk transition queue.   A client upon°dONLNdR*H8*Oreceiving such a message can ask Remote Access (through a network validate hook°dONLNd¢8HF˝*Xpassed to the client) if a specific network is still reachable.  If the network is still°dONLNd˚FHT*Ureachable, true will be returned.  A client can then continue to check other networks°dONLNdQTHb *Whe is interested in until he has learned the status of each of them.  After a client is°dONLNd©bHpÏ*Ifinished checking his networks he returns to Remote Access where the next°dONLNdÛpH~6*,AppleTalk transition queue client is called.°dONLNd åHö*USince the "Network Transition Event" is transitional, it is important to realize that°dONLNdvöH®*Tthe information that the network validate hook returns is only valid if a client has°dONLNdÀ®H∂*Yjust been called as a result of a transition.  In other words, a client can only validate°dONLNd%∂Hƒ*Tnetworks when it has been called to handle a "Network Transition Event".  It is also°dONLNdzƒH“*Timportant to realize that the "Network Transition Event" can be called as the result°dONLNdœ“H‡ *Rof an interrupt, so a client should obey all of the normal conventions involved at°dONLNd"‡HÓ*Tbeing called at this time (i.e. don't ask for memory from the memory manager, etc.).°dONLNdw¸H
  1232. *NThe following information assumes you have already installed yourself into the°dONLNdΔ
  1233. HÂ*AppleTalk transition queue.
  1234. °dONLNd‚(H8˙* ATTransNetworkTransition
  1235. °dONLNd˚8HF˚*GThe ATTransNetworkTransition event will be generated whenever a network°dONLNd    CFHTˇ*Ptransition occurs.  You will be passed the following information using C calling°dONLNd    îTHbë* conventions:,
  1236. Courier
  1237.     °dONLNd    °lHwŒ*NClientTransitionHandler(long theEvent, Ptr aqe, TNetworkTransition *thetrans);°dONLNd    ÄHãp*theEvent°dONLNd    ˘Äêã§)H<---°dONLNd    ˛Ä¥ãw)$'will be set to ATTransNetworkTransition°dONLNd
  1238. &äHïW(íHaqe°dONLNd
  1239. +äêï§)H<---°dONLNd
  1240. 0ä¥ïT)$ points to transition task struct°dONLNd
  1241. QîHüp(úHthetrans°dONLNd
  1242. Zîêü§)H<---°dONLNd
  1243. _î¥üw)$'points to the TNetworkTransition struct
  1244. °dONLNd
  1245. â≤H¿è(ºH:The TNetworkTransition struct passed to you is defined as:
  1246. +H519ˇ@dˇ ˇˇˇˇd
  1247. d, Palatino
  1248. .+H-Apple Remote Access API)ê External Reference Specification,
  1249. Courier
  1250.     °dONLNdHHS`(PH8typedef pascal ulong (*NetValidProcPtr)(uPtr,AddrBlock);°dONLNd9\HgÌ*!typedef struct TNetworkTransition°dONLNd[fHqM*
  1251. {°dONLNd^pR{ì+
  1252.  
  1253.  
  1254. uPtr private;°dONLNdlp¥{Y)b!// pointer used internally by 976°dONLNdèzRÖ„(ÇRNetValidProcPtr netValidProc;°dONLNd≠z¸Ö∞)™$// pointer to the network valid proc°dONLNd”ÑRè (åRBoolean newConnectivity;°dONLNdÏÑÿè‹)Ü4// true=new connectivity, false=loss of connectivity°dONLNd!éHô±(ñH} TNetworkTransition;
  1255. °dONLNd7¶H¥¸*OTo check a network number for validity the client uses the netValidProc to call°dONLNdá¥H¬I*0Remote Access.  This call is defined as follows:
  1256.     °dONLNd∏ÃH◊∫*Jlong netValidProc(TNetworkTransition *thetrans, unsigned long theAddress);°dONLNd‡HÎp*thetrans°dONLNd ‡êΧ)H--->°dONLNd‡¥Î‡)$<pass in the TNetworkTransition struct given to you when your°dONLNdQÍêı&(Úêtransition handler was called.°dONLNdpÙHˇ(¸H theAddress °dONLNd|Ùêˇ§)H--->°dONLNdÅÙ¥ˇ)$Gthis is the network address you want checked.  The format of theAddress°dONLNd…˛ÿ    ·+$
  1257. 5is the same as for the struct AddrBlock as defined in°dONLNdˇÿ*
  1258. AppleTalk.h:
  1259. °dONLNdê*Ç(&ê'Bytes 3 & 2 (High Word): Network Number°dONLNd:*ê8    *Byte 1: Node Number°dONLNdQ8êFL* Byte 0 (Low Byte): Socket Number°dONLNdrOH]ë(YH Return codes°dONLNdÅ]Rkt+
  1260. TRUE°dONLNdÜ]êk)>network is still reachable°dONLNd¢kRyx(uRFALSE°dONLNd®kêy;)>network is no longer reachable
  1261. °dONLNd«áHóñ(ìH Error Codes
  1262.     °dONLNd”ßH≤›*Q// ------------------------------------------------------------------------------°dONLNd%±Hº˜*
  1263. #// MNP Error Codes - MNPInterface.h°dONLNdIªHΔ›*
  1264. Q// ------------------------------------------------------------------------------°dONLNdõœH⁄¨*#define MNP_ERR_BASE°dONLNd∞œ¥⁄Õ)l-6050°dONLNd∑œ ⁄±)l// base for MNP driver errors°dONLNd’„HÓ˜(ÎH##define ERR_MNP_NEGOTIATION_FAILURE°dONLNd˘„Ó^)Δ(MNP_ERR_BASE-1)°dONLNd
  1265. „hÓ)Z#// Connection parameter negotiation°dONLNd8Ìh¯ö*
  1266.  
  1267. // failure°dONLNdC˜HË(ˇH #define ERR_MNP_CONNECT_TIME_OUT°dONLNdd˜^)Δ(MNP_ERR_BASE-2)°dONLNdu˜h)Z#// Connect request (acceptor mode) °dONLNd£h §*
  1268. // timed out°dONLNd∞ HŸ(H#define ERR_MNP_NOT_CONNECTED°dONLNdŒ ^)Δ(MNP_ERR_BASE-3)°dONLNdfl h∏)Z// Not connected°dONLNdH ª(H#define ERR_MNP_ABORTED°dONLNd ^)Δ(MNP_ERR_BASE-4)°dONLNdh )Z // Request aborted by disconnect°dONLNdCh*ö*
  1269.  
  1270. // request°dONLNdN)H4Ú(1H"#define ERR_MNP_ATTENTION_DISABLED°dONLNdq)4^)Δ(MNP_ERR_BASE-5)°dONLNdÇ)h4)Z // Link attention service is not°dONLNd≠3h>ö*
  1271.  
  1272. // enabled°dONLNd∏=HH˜(EH##define ERR_MNP_CONNECT_RETRY_LIMIT°dONLNd‹=H^)Δ(MNP_ERR_BASE-6)°dONLNdÌ=hH)Z#// Connect (initiator mode) request°dONLNdGhR€*
  1273. // retry limit reached.°dONLNd4QH\˜(YH##define ERR_MNP_COMMAND_IN_PROGRESS°dONLNdXQ\^)Δ(MNP_ERR_BASE-7)°dONLNdiQh\)Z// Command already in progress.°dONLNdâ[HfÌ(cH!#define ERR_MNP_ALREADY_CONNECTED°dONLNd´[f^)Δ(MNP_ERR_BASE-8)°dONLNdº[hf)Z"// Connection already established.°dONLNdfleHp(mH%#define ERR_MNP_INCOMPATIBLE_PROT_LVL°dONLNdep^)Δ(MNP_ERR_BASE-9)°dONLNdehpÔ)Z// Connection failed due to°dONLNd;ohz*
  1274. // incompatible protocol levels°dONLNd[yHÑÌ(ÅH!#define ERR_MNP_HANDSHAKE_FAILURE°dONLNd}yÑc)Δ(MNP_ERR_BASE-10)°dONLNdèyhÑ)Z// Connection handshake failed.°dONLNdØóH¢›(üHQ// ------------------------------------------------------------------------------°dONLNd    °H¨=*
  1275. 1// Netshare Error Codes - RemoteAccessInterface.h°dONLNd    3´H∂›*
  1276. Q// ------------------------------------------------------------------------------°dONLNd    ÖøH ò*#define ERR_BASE°dONLNd    ñø¥ Õ)l-5800
  1277. (Òê20ˇTdˇ ˇˇˇˇd
  1278. d, Palatino
  1279. .+H-Apple Remote Access API)ê External Reference Specification,
  1280. Courier
  1281.     °dONLNdRH]¿(ZH#define ERR_NOTCONNECTED°dONLNdR ]\)ÿ (ERR_BASE-0)°dONLNd&\HgŸ(dH#define ERR_CONNECTIONABORTED°dONLNdD\ g\)ÿ (ERR_BASE-1)°dONLNdQfHq‘(nH#define ERR_ALREADYCONNECTED°dONLNdnf q\)ÿ (ERR_BASE-2)°dONLNd{pH{¸(xH$#define ERR_COMMANDALREADYINPROGRESS°dONLNd†p {\)ÿ (ERR_BASE-3)°dONLNd≠zHÖ∂(ÇH#define ERR_BADVERSION°dONLNdƒz Ö\)ÿ (ERR_BASE-4)°dONLNd—ÑHè∂(åH#define ERR_INSHUTDOWN°dONLNdËÑ è\)ÿ (ERR_BASE-5)°dONLNdıéHôfi(ñH#define ERR_CONNECTIONABORTING°dONLNdé ô\)ÿ (ERR_BASE-6)°dONLNd!òH£ (†H#define ERR_ALREADYENABLED°dONLNd<ò £\)ÿ (ERR_BASE-7)°dONLNdI¢H≠ (™H#define ERR_ZONEBUFBADSIZE°dONLNdd¢ ≠\)ÿ (ERR_BASE-8)°dONLNdq¨H∑œ(¥H#define ERR_CONNECTTIMEDOUT°dONLNd稠∑\)ÿ (ERR_BASE-9)°dONLNdö∂H¡„(æH#define ERR_CONNECTUSERTIMEDOUT°dONLNd∫∂ ¡a)ÿ
  1282. (ERR_BASE-10)°dONLNd»¿HÀ¿(»H#define ERR_BADPARAMETER°dONLNd·¿ Àa)ÿ
  1283. (ERR_BASE-11)°dONLNdÔ H’ª(“H#define ERR_NOMULTINODE°dONLNd  ’a)ÿ
  1284. (ERR_BASE-12)°dONLNd‘Hfl (‹H#define ERR_ATALKNOTACTIVE°dONLNd0‘ fla)ÿ
  1285. (ERR_BASE-13)°dONLNd>fiHÈŸ(ÊH#define ERR_NOCALLBACKSUPPORT°dONLNd\fi Èa)ÿ
  1286. (ERR_BASE-14)°dONLNdjËHÛŸ(H#define ERR_NOTOPENEDBYTHISPB°dONLNdàË Ûa)ÿ
  1287. (ERR_BASE-15)°dONLNdñÚH˝±(˙H#define ERR_NOGLOBALS°dONLNd¨Ú ˝a)ÿ
  1288. (ERR_BASE-16)°dONLNd∫¸H≈(H#define ERR_NOSMARTBUFFER°dONLNd‘¸ a)ÿ
  1289. (ERR_BASE-17)°dONLNd‚H¿(H#define ERR_BADATALKVERS°dONLNd˚ a)ÿ
  1290. (ERR_BASE-18)°dONLNd    H¿(H#define ERR_VLD8_CONNECT°dONLNd" %)ÿ0°dONLNd$H%≈("H#define ERR_VLD8_CALLBACK°dONLNd> %a)ÿ
  1291. (ERR_BASE-19)°dONLNdL$H/œ(,H#define ERR_VLD8_BADVERSION°dONLNdh$ /a)ÿ
  1292. (ERR_BASE-20)°dONLNdv.H9¿(6H#define ERR_VLD8_BADUSER°dONLNdè. 9a)ÿ
  1293. (ERR_BASE-21)°dONLNdù8HC‘(@H#define ERR_VLD8_BADPASSWORD°dONLNd∫8 Ca)ÿ
  1294. (ERR_BASE-22)°dONLNd»BHM¿(JH#define ERR_VLD8_BADLINK°dONLNd·B Ma)ÿ
  1295. (ERR_BASE-23)°dONLNdÔLHWÚ(TH"#define ERR_VLD8_NOCALLBACKALLOWED°dONLNdL Wa)ÿ
  1296. (ERR_BASE-24)°dONLNd VHaÌ(^H!#define ERR_VLD8_ALLCBSERVERSBUSY°dONLNdBV aa)ÿ
  1297. (ERR_BASE-25)°dONLNdP`HkË(hH #define ERR_VLD8_GUESTNOTALLOWED°dONLNdq` ka)ÿ
  1298. (ERR_BASE-26)°dONLNdjHuÌ(rH!#define ERR_VLD8_SERVERISIMPOSTER°dONLNd°j ua)ÿ
  1299. (ERR_BASE-27)°dONLNdØtHË(|H #define ERR_VLD8_LOGINNOTENABLED°dONLNd–t a)ÿ
  1300. (ERR_BASE-28)°dONLNdfi~Hâ˜(ÜH##define ERR_REMOTEPORTALREADYEXISTS°dONLNd~ âa)ÿ
  1301. (ERR_BASE-29)°dONLNdàHì (êH#define ERR_OPENNOTALLOWED°dONLNd+à ìa)ÿ
  1302. (ERR_BASE-30)°dONLNd9íHù‘(öH#define ERR_NOUSERSANDGROUPS°dONLNdVí ùa)ÿ
  1303. (ERR_BASE-31)°dONLNddúHß¿(§H#define ERR_PORTSHUTDOWN°dONLNd}ú ßa)ÿ
  1304. (ERR_BASE-32)°dONLNdã¶H±‘(ÆH#define ERR_PORTDOESNOTEXIST°dONLNd®¶ ±a)ÿ
  1305. (ERR_BASE-33)°dONLNd∂∞HªŸ(∏H#define ERR_PWNEEDEDFORENABLE°dONLNd‘∞ ªa)ÿ
  1306. (ERR_BASE-34)°dONLNd‚∫H≈ß(¬H#define ERR_DAMAGED°dONLNdˆ∫¥≈ı)l
  1307. (ERR_BASE-35)°dONLNdƒHœ‘(ÃH#define ERR_NETCONFIGCHANGED°dONLNd!ƒ œa)ÿ
  1308. (ERR_BASE-36)°dONLNd/ŒHŸ≈(÷H/* 2.0 and above only… */°dONLNdIÿH„k*
  1309. #define°dONLNdQÿt„‚),ERR_NOSUPPORT_ATREMOTE°dONLNdhÿ „a)¨
  1310. (ERR_BASE-37)°dONLNdv‚HÌ„(ÍH#define ERR_CONFLICTING_REQUEST°dONLNdñ‚ Ìa)ÿ
  1311. (ERR_BASE-38)°dONLNd§ÏH˜k(ÙH#define°dONLNd¨Ït˜ˆ),ERR_VLD8_INVALIDAUTHMETHOD°dONLNd«Ï ˜a)¨
  1312. (ERR_BASE-39)°dONLNd’ˆHk(˛H#define°dONLNd›ˆt…),ERR_VLD8_CONTINUE°dONLNdÔˆ a)¨
  1313. (ERR_BASE-40)°dONLNd˝H k(H#define°dONLNdt Œ),ERR_PWCHANGECANCEL°dONLNd  a)¨
  1314. (ERR_BASE-41)°dONLNd&
  1315. H (H'#define ERR_VLD8_MANUALPASSWORDREQUIRED°dONLNdN
  1316.  a)ÿ
  1317. (ERR_BASE-50)°dONLNd\H)ì(&H#define ERR_END°dONLNdl¥)O)lERR_VLD8_MANUALPASSWORDREQUIRED°dONLNdåh)‡)¥/* must be last error */°dONLNd•FHQ›(NHQ// ------------------------------------------------------------------------------°dONLNd˜PH[B*
  1318. 2// Connection Control Language Error Codes - CCL.h°dONLNd*ZHe›*
  1319. Q// ------------------------------------------------------------------------------°dONLNd|nHyk*#define°dONLNdÑntyø),cclErr_BaseCode°dONLNdînÓy)z-6000°dONLNdöxHÉk(ÄH#define°dONLNd¢xtÉ›),cclErr_AbortMatchRead°dONLNd∏xÓÉ>)z cclErr_BaseCode°dONLNd xhÉ)z// internal error used to abort°dONLNdÙÇhç§*
  1320. //match read°dONLNd    åHók(îH#define°dONLNd        åtóí),cclErr°dONLNd    åÓóW)z(cclErr_BaseCode - 6)°dONLNd    'åhóΩ)z// CCL error base°dONLNd    9ñH°≈(ûH#define cclErr_CloseError°dONLNd    SñÓ°W)¶(cclErr_BaseCode - 7)°dONLNd    iñh°)z$// There is at least one script open°dONLNd    é†H´fi(®H#define cclErr_ScriptCancelled°dONLNd    ≠†Ó´W)¶(cclErr_BaseCode - 8)°dONLNd    √†h´¬)z// Script Canceled°dONLNd    ◊™Hµk(≤H#define°dONLNd    fl™tµ”),cclErr_TooManyLines°dONLNd    Û™ÓµW)z(cclErr_BaseCode - 9)°dONLNd
  1321.     ™hµÔ)z// Script contains too many°dONLNd
  1322. /¥høê*
  1323. // lines°dONLNd
  1324. 8æH…œ(ΔH#define cclErr_ScriptTooBig°dONLNd
  1325. TæÓ…\)¶(cclErr_BaseCode - 10)°dONLNd
  1326. kæh…Ô)z// Script contains too many
  1327. (Òê21ˇ.dˇ ˇˇˇˇd
  1328. d, Palatino
  1329. .+H-Apple Remote Access API)ê External Reference Specification,
  1330. Courier
  1331.     °dONLNdHhS©+ê#
  1332. // characters°dONLNdRH]k(ZH#define°dONLNdRt]›),cclErr_NotInitialized°dONLNd,RÓ]\)z(cclErr_BaseCode - 11)°dONLNdCRh]«)z// CCL has not been°dONLNda\hgÆ*
  1333. // initialized°dONLNdpfHqk(nH#define°dONLNdxftqÁ),cclErr_CancelInProgress°dONLNdêfÓq\)z(cclErr_BaseCode - 12)°dONLNdßfhq÷)z// Cancel in progress.°dONLNdæpH{k(xH#define°dONLNdΔpt{›),cclErr_PlayInProgress°dONLNd‹pÓ{\)z(cclErr_BaseCode - 13)°dONLNdÛph{Í)z// Play command already in°dONLNdzhÖ§*
  1334. // progress.°dONLNd%ÑHèk(åH#define°dONLNd-Ñtèµ),
  1335. cclErr_ExitOK°dONLNd;ÑÓè\)z(cclErr_BaseCode - 14)°dONLNdRÑhè÷)z// Exit with no error.°dONLNdiéHôk(ñH#define°dONLNdqétôø),cclErr_BadLabel°dONLNdÅéÓô\)z(cclErr_BaseCode - 15)°dONLNdòéhô÷)z// Label out of range.°dONLNdØòH£≈(†H#define cclErr_BadCommand°dONLNd…òÓ£\)¶(cclErr_BaseCode - 16)°dONLNd‡òh£≥)z// Bad command.°dONLNd¢H≠k(™H#define°dONLNd¯¢t≠›),cclErr_EndOfScriptErr°dONLNd¢Ó≠\)z(cclErr_BaseCode - 17)°dONLNd%¢h≠Â)z// End of script reached,°dONLNdI¨h∑¬*
  1336. // expecting Exit.°dONLNd\∂H¡k(æH#define°dONLNdd∂t¡‚),cclErr_MatchStrIndxErr°dONLNd{∂Ó¡\)z(cclErr_BaseCode - 18)°dONLNdí∂h¡Ù)z// Match string index is out°dONLNd∏¿DÀÖ(»D
  1337. // of bounds.°dONLNdΔ H’k(“H#define°dONLNdŒ t’ø),cclErr_ModemErr°dONLNdfi Ó’\)z(cclErr_BaseCode - 19)°dONLNdı h’Â)z// Modem error, modem not°dONLNd‘åfl“+$
  1338. // responding.°dONLNd)fiHÈk(ÊH#define°dONLNd1fitÈ…),cclErr_NoDialTone°dONLNdCfiÓÈ\)z(cclErr_BaseCode - 20)°dONLNdZfihÈ∏)z// No dial tone.°dONLNdkËHÛk(H#define°dONLNdsËtÛ”),cclErr_NoCarrierErr°dONLNdáËÓÛ\)z(cclErr_BaseCode - 21)°dONLNdûËhÛÆ)z// No carrier.°dONLNd≠ÚH˝k(˙H#define°dONLNdµÚt˝Œ),cclErr_LineBusyErr°dONLNd»ÚÓ˝\)z(cclErr_BaseCode - 22)°dONLNdflÚh˝©)z
  1339. // Line busy.°dONLNd̸Hk(H#define°dONLNdı¸tŒ),cclErr_NoAnswerErr°dONLNd¸Ó\)z(cclErr_BaseCode - 23)°dONLNd¸h©)z
  1340. // No answer.°dONLNd-Hk(H#define°dONLNd5tÁ),cclErr_NoOriginateLabel°dONLNdMÓ\)z(cclErr_BaseCode - 24)°dONLNddh∏)z// No @ORIGINATE°dONLNduHk(H#define°dONLNd}tÿ),cclErr_NoAnswerLabel°dONLNdíÓ\)z(cclErr_BaseCode - 25)°dONLNd©h©)z
  1341. // No @ANSWER°dONLNd∑H%k("H#define°dONLNdøt%ÿ),cclErr_NoHangUpLabel°dONLNd‘Ó%\)z(cclErr_BaseCode - 26)°dONLNdÎh%©)z
  1342. // No @HANGUP°dONLNd˘8HC›(@HQ// ------------------------------------------------------------------------------°dONLNdKBHM=*
  1343. 1// Link Tool Manager Error Codes - LTMInterface.h°dONLNd}LHW›*
  1344. Q// ------------------------------------------------------------------------------°dONLNdœ`Hkk*#define°dONLNd◊`tk∞), ERR_LTM_BASE°dONLNd‰`¸k)à-5900°dONLNdÎ`Vk”)Z// base of errors for LTM°dONLNdjHuÚ(rH"#define ERR_LTM_LISTENER_ID_IN_USE°dONLNd(j¸uL)¥(ERR_LTM_BASE-1)°dONLNd9jVu
  1345. )Z$// Specified  Listener identifier is°dONLNdhtVÉ*
  1346.     // in use°dONLNdr~Hâœ(ÜH#define ERR_LTM_NO_LISTENER°dONLNdé~¸âL)¥(ERR_LTM_BASE-2)°dONLNdü~Vâ
  1347. )Z$// Listener of specified type is not°dONLNdŒàVìí*
  1348. // available°dONLNd€íHù`(öH8#define ERR_LTM_RESOURCE_NOT_REGISTERED (ERR_LTM_BASE-3)°dONLNdíhù(öh$// Listener of specified type is not°dONLNdDúhß§*
  1349. // available°dONLNdQ¶H±Ë(ÆH #define ERR_LTM_PORT_NOT_CLAIMED°dONLNdr¶¸±L)¥(ERR_LTM_BASE-4)°dONLNdɶV±)Z"// claim request failed because to°dONLNd∞∞Vª°*
  1350. // port is busy°dONLNd¿∫H≈˜(¬H##define ERR_LTM_COMMAND_NOT_ALLOWED°dONLNd‰∫¸≈L)¥(ERR_LTM_BASE-5)°dONLNdı∫V≈Á)Z// LTM command not allowed on°dONLNdƒVœ´*
  1351. // specified port°dONLNd/ŒHŸœ(÷H#define ERR_LTM_BAD_VERSION°dONLNdKŒ¸ŸL)¥(ERR_LTM_BASE-6)°dONLNd\ŒVŸŒ)Z// connect failed due to°dONLNdÿV„‚*
  1352. // incompatible LTM versions°dONLNdú‚H̘(ÍH##define ERR_LTM_ARBITRATION_TIMEOUT°dONLNd¿‚¸ÌL)¥(ERR_LTM_BASE-7)°dONLNd—‚VÌ)Z"// Connection failed due to a time°dONLNd˛ÏV˜ÿ*
  1353. // out during the listener°dONLNd    #ˆVú*
  1354. // arbitration°dONLNd    2H fi(H#define ERR_LTM_KODE_NOT_FOUND°dONLNd    Q¸ L)¥(ERR_LTM_BASE-8)°dONLNd    bV Á)Z// kode resource not found in°dONLNd    ä
  1355. V´*
  1356. // specified file°dONLNd    úHŸ(H#define ERR_LTM_PORT_DISPOSED°dONLNd    ∫¸L)¥(ERR_LTM_BASE-9)°dONLNd    ÀV˚)Z!// A Dispose Port call caused the°dONLNd    ˜V)µ*
  1357. // request to fail.°dONLNd
  1358. (H3Ë(0H #define ERR_LTM_RESOURCE_CLAIMED°dONLNd
  1359. ,(¸3Q)¥(ERR_LTM_BASE-10)°dONLNd
  1360. >(V3)Z"// call failed because resource is°dONLNd
  1361. k2V=∞*
  1362. // already claimed°dONLNd
  1363. ~<HG(DH&#define ERR_LTM_PORT_RESOURCES_CLAIMED°dONLNd
  1364. •< Gu)ÿ(ERR_LTM_BASE-11)°dONLNd
  1365. ∑<åG)l// call failed because the°dONLNd
  1366. fiFåQˇ*
  1367. // port’s resources are°dONLNd På[Ê*
  1368. // already claimed°dONLNd ZHe¸(bH$#define ERR_LTM_RESOURCE_NOT_CLAIMED°dONLNd :Z
  1369. e_)¬(ERR_LTM_BASE-12)°dONLNd LZhe)^#// call failed because the resource°dONLNd {dho∏*
  1370. // was unclaimed°dONLNd ånHyt(vH<#define ERR_LTM_PORT_RESOURCES_NOT_CLAIMED (ERR_LTM_BASE-13)°dONLNd …nåy(vå// The LTM port's resources°dONLNd xåÉÎ*
  1371. // are NOT claimed.°dONLNd ÇHçfi(äH#define ERR_LTM_PORT_UNCLAIMED°dONLNd #ǸçQ)¥(ERR_LTM_BASE-14)°dONLNd 5ÇVç‚)Z// LTM listen port unclaimed°dONLNd RåHóÚ(îH"#define ERR_LTM_CONNECTION_REFUSED°dONLNd uå¸óQ)¥(ERR_LTM_BASE-15)°dONLNd áåVóÒ)Z// LTM listener refused connect°dONLNd ∞ñV°à*
  1372.  
  1373. // request°dONLNd ª†H´Ÿ(®H#define ERR_LTM_CLAIM_ABORTED°dONLNd Ÿ†¸´Q)¥(ERR_LTM_BASE-16)°dONLNd ΆV´ˆ)Z // LTM claim call aborted due to°dONLNd
  1374. ™Vµ‚*
  1375. // LTM_ARB_CLAIM_CANCEL call°dONLNd
  1376. 3¥HøË(ºH #define ERR_LTM_END_OF_PORT_LIST°dONLNd
  1377. T¥¸øQ)¥(ERR_LTM_BASE-17)°dONLNd
  1378. f¥Vø)Z#// End of open port list reached in°dONLNd
  1379. îæV…Ï*
  1380. // current port status session
  1381. (Òê22ˇòdˇ ˇˇˇˇd
  1382. d, Palatino
  1383. .+H-Apple Remote Access API)ê External Reference Specification,
  1384. Courier
  1385.     °dONLNdRH]Ÿ(ZH#define ERR_LTM_NOT_CONNECTED°dONLNdR¸]Q)¥(ERR_LTM_BASE-18)°dONLNd0RV]´)Z// Not connected.°dONLNdB\HgÚ(dH"#define ERR_LTM_CONNECTION_ABORTED°dONLNde\¸gQ)¥(ERR_LTM_BASE-19)°dONLNdw\VgÁ)Z// Connection request aborted°dONLNdïfHq (nH#define ERR_LTM_BAD_LENGTH°dONLNd∞f¸qQ)¥(ERR_LTM_BASE-20)°dONLNd¬fVq)Z"// Length of write request exceeds°dONLNdÔpV{ç*
  1386. // maximum.°dONLNd˚zHÖŸ(ÇH#define ERR_LTM_BAD_PARAMETER°dONLNdz¸ÖQ)¥(ERR_LTM_BASE-21)°dONLNd+zVÖ´)Z// Bad parameter.°dONLNd=ÑHè˜(åH##define ERR_LTM_COMMAND_IN_PROGRESS°dONLNdaѸèQ)¥(ERR_LTM_BASE-22)°dONLNdsÑVèÒ)Z// Command already in progress.°dONLNdìéHô≈(ñH#define ERR_LTM_CONNECTED°dONLNd≠é¸ôQ)¥(ERR_LTM_BASE-23)°dONLNdøéVôÿ)Z// Connection established.°dONLNd⁄òH£k(†H#define°dONLNd‚òt£Ï),ERR_LTM_CONNECT_CANCELED°dONLNd˚ò¸£V)à (ERR_LTM_BASE-24)°dONLNdòh£)l// Connection request canceled.°dONLNd.¢H≠k(™H#define°dONLNd6¢t≠Ï),ERR_LTM_CONNECT_TIMEDOUT°dONLNdO¢¸≠V)à (ERR_LTM_BASE-25)°dONLNdb¢h≠€)l// Connection time out.°dONLNdz¨H∑k(¥H#define°dONLNdǨt∑”),ERR_LTM_NO_DEFAULTS°dONLNdñ¨¸∑V)à (ERR_LTM_BASE-26)°dONLNd©¨h∑)l // Could not get default info...°dONLNd ∂H¡k(æH#define°dONLNd“∂t¡ƒ),ERR_LTM_GOOD_BYE°dONLNd„∂¸¡Q)à(ERR_LTM_BASE-27)°dONLNdı∂V¡ˆ)Z // The driver is going away in a°dONLNd ¿VÀ°*
  1387. // rude fashion
  1388. (Òê23ˇ